Skip to content

Commit 01e03c2

Browse files
author
Julien Couvreur
authored
Extensions: allow more CREFs (#80114)
1 parent 9e67487 commit 01e03c2

File tree

3 files changed

+363
-47
lines changed

3 files changed

+363
-47
lines changed

src/Compilers/CSharp/Portable/Binder/Binder_Crefs.cs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
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;
56
using System.Collections.Generic;
67
using System.Collections.Immutable;
78
using 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

src/Compilers/CSharp/Portable/Binder/WithCrefTypeParametersBinder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ private MultiDictionary<string, TypeParameterSymbol> CreateTypeParameterMap()
6363
case SyntaxKind.IndexerMemberCref:
6464
case SyntaxKind.OperatorMemberCref:
6565
case SyntaxKind.ConversionOperatorMemberCref:
66+
case SyntaxKind.ExtensionMemberCref:
6667
{
6768
AddTypeParameters((MemberCrefSyntax)_crefSyntax, map);
6869
break;

0 commit comments

Comments
 (0)