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,19 @@ 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+ IEnumerable < NamedTypeSymbol > candidateTypes = containerOpt switch
294+ {
295+ null => enumerateCandidateTypes ( containerOpt , syntax , diagnostics ) ,
296+ NamedTypeSymbol container => container . GetTypeMembers ( "" ) ,
297+ _ => [ ]
298+ } ;
299+
300+ foreach ( var nested in candidateTypes )
299301 {
300- if ( ! nested . IsExtension || nested . Arity != extensionArity || nested . ExtensionParameter is null )
302+ if ( ! nested . IsExtension
303+ || nested . Arity != extensionArity
304+ || nested . ExtensionParameter is null
305+ || nested is not { ContainingType : { ContainingType : null } } ) // only consider extension blocks in top-level types
301306 {
302307 continue ;
303308 }
@@ -365,6 +370,36 @@ ImmutableArray<Symbol> computeSortedAndFilteredCrefExtensionMembers(NamedTypeSym
365370
366371 return sortedSymbolsBuilder . ToImmutableAndFree ( ) ;
367372 }
373+
374+ IEnumerable < NamedTypeSymbol > enumerateCandidateTypes ( NamespaceOrTypeSymbol ? container , SyntaxNode syntax , BindingDiagnosticBag diagnostics )
375+ {
376+ CompoundUseSiteInfo < AssemblySymbol > useSiteInfo = GetNewCompoundUseSiteInfo ( diagnostics ) ;
377+ LookupResult result = LookupResult . GetInstance ( ) ;
378+ this . LookupSymbolsOrMembersInternal (
379+ result ,
380+ container ,
381+ name : "" ,
382+ arity : 0 ,
383+ basesBeingResolved : null ,
384+ options : LookupOptions . AllNamedTypesOnArityZero | LookupOptions . NamespacesOrTypesOnly ,
385+ diagnose : false ,
386+ useSiteInfo : ref useSiteInfo ) ;
387+
388+ diagnostics . Add ( syntax , useSiteInfo ) ;
389+
390+ if ( result . IsMultiViable )
391+ {
392+ foreach ( var symbol in result . Symbols )
393+ {
394+ if ( symbol is NamedTypeSymbol namedType )
395+ {
396+ yield return namedType ;
397+ }
398+ }
399+ }
400+
401+ result . Free ( ) ;
402+ }
368403 }
369404
370405 // NOTE: not guaranteed to be a method (e.g. class op_Addition)
0 commit comments