22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5+ using System ;
56using System . Collections . Generic ;
67using System . Collections . Immutable ;
78using System . Diagnostics ;
@@ -224,12 +225,6 @@ private ImmutableArray<Symbol> BindExtensionMemberCref(ExtensionMemberCrefSyntax
224225 {
225226 CheckFeatureAvailability ( syntax , MessageID . IDS_FeatureExtensions , diagnostics ) ;
226227
227- if ( containerOpt is not NamedTypeSymbol namedContainer )
228- {
229- ambiguityWinner = null ;
230- return ImmutableArray < Symbol > . Empty ;
231- }
232-
233228 int arity = 0 ;
234229 TypeArgumentListSyntax ? typeArgumentListSyntax = null ;
235230 CrefParameterListSyntax ? parameters = null ;
@@ -256,7 +251,7 @@ private ImmutableArray<Symbol> BindExtensionMemberCref(ExtensionMemberCrefSyntax
256251
257252 TypeArgumentListSyntax ? extensionTypeArguments = syntax . TypeArgumentList ;
258253 int extensionArity = extensionTypeArguments ? . Arguments . Count ?? 0 ;
259- ImmutableArray < Symbol > sortedSymbols = computeSortedAndFilteredCrefExtensionMembers ( namedContainer , memberName , extensionArity , arity , extensionTypeArguments , diagnostics , syntax ) ;
254+ ImmutableArray < Symbol > sortedSymbols = computeSortedAndFilteredCrefExtensionMembers ( containerOpt , memberName , extensionArity , arity , extensionTypeArguments , diagnostics , syntax ) ;
260255
261256 if ( sortedSymbols . IsDefaultOrEmpty )
262257 {
@@ -268,7 +263,7 @@ private ImmutableArray<Symbol> BindExtensionMemberCref(ExtensionMemberCrefSyntax
268263
269264 return ProcessCrefMemberLookupResults ( sortedSymbols , arity , syntax , typeArgumentListSyntax , parameters , out ambiguityWinner , diagnostics ) ;
270265
271- ImmutableArray < Symbol > computeSortedAndFilteredCrefExtensionMembers ( NamedTypeSymbol container , string name , int extensionArity , int arity , TypeArgumentListSyntax ? extensionTypeArguments , BindingDiagnosticBag diagnostics , ExtensionMemberCrefSyntax syntax )
266+ ImmutableArray < Symbol > computeSortedAndFilteredCrefExtensionMembers ( NamespaceOrTypeSymbol ? containerOpt , string name , int extensionArity , int arity , TypeArgumentListSyntax ? extensionTypeArguments , BindingDiagnosticBag diagnostics , ExtensionMemberCrefSyntax syntax )
272267 {
273268 Debug . Assert ( name is not null ) ;
274269
@@ -295,9 +290,12 @@ ImmutableArray<Symbol> computeSortedAndFilteredCrefExtensionMembers(NamedTypeSym
295290 CompoundUseSiteInfo < AssemblySymbol > useSiteInfo = this . GetNewCompoundUseSiteInfo ( diagnostics ) ;
296291 ArrayBuilder < Symbol > ? sortedSymbolsBuilder = null ;
297292
298- foreach ( var nested in container . GetTypeMembers ( ) )
293+ foreach ( var nested in candidateTypes ( containerOpt ) )
299294 {
300- if ( ! nested . IsExtension || nested . Arity != extensionArity || nested . ExtensionParameter is null )
295+ if ( ! nested . IsExtension
296+ || nested . Arity != extensionArity
297+ || nested . ExtensionParameter is null
298+ || nested is not { ContainingType : { ContainingType : null } } ) // only consider extension blocks in top-level types
301299 {
302300 continue ;
303301 }
@@ -364,6 +362,23 @@ ImmutableArray<Symbol> computeSortedAndFilteredCrefExtensionMembers(NamedTypeSym
364362 }
365363
366364 return sortedSymbolsBuilder . ToImmutableAndFree ( ) ;
365+
366+ ImmutableArray < NamedTypeSymbol > candidateTypes ( NamespaceOrTypeSymbol ? containerOpt )
367+ {
368+ if ( containerOpt is NamedTypeSymbol namedType )
369+ {
370+ return namedType . GetTypeMembers ( "" ) ;
371+ }
372+
373+ NamedTypeSymbol ? containingType = ContainingType ;
374+ if ( containingType is null )
375+ {
376+ return [ ] ;
377+ }
378+
379+ NamedTypeSymbol ? enclosingType = containingType . IsExtension ? containingType . ContainingType : containingType ;
380+ return enclosingType ? . GetTypeMembers ( "" ) ?? [ ] ;
381+ }
367382 }
368383 }
369384
0 commit comments