Skip to content

Commit 37bad6f

Browse files
author
Julien Couvreur
committed
Extension indexers: allow and resolve extension indexers
1 parent 147ebc0 commit 37bad6f

37 files changed

+6689
-548
lines changed

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ internal MethodInfo ReplaceWithExtensionImplementation(out bool wasError)
9191
var setMethod = replace(SetMethod);
9292
Symbol symbol = ReferenceEquals(Symbol, Method) && method is not null ? method : Symbol;
9393

94-
Debug.Assert(SetMethod?.IsExtensionBlockMember() != true);
9594
wasError = (Method is not null && method is null) || (SetMethod is not null && setMethod is null);
9695

9796
return new MethodInfo(symbol, method, setMethod);
@@ -634,10 +633,11 @@ private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundI
634633
{
635634
var coreValueKind = valueKind & ValueKindSignificantBitsMask;
636635
AccessorKind accessorKind = GetIndexerAccessorKind(indexerAccess, valueKind);
637-
var useSetAccessor = coreValueKind == BindValueKind.Assignable && indexerAccess.Indexer.RefKind != RefKind.Ref;
636+
PropertySymbol indexer = indexerAccess.Indexer;
637+
var useSetAccessor = coreValueKind == BindValueKind.Assignable && indexer.RefKind != RefKind.Ref;
638638
var accessorForDefaultArguments = useSetAccessor
639-
? indexerAccess.Indexer.GetOwnOrInheritedSetMethod()
640-
: indexerAccess.Indexer.GetOwnOrInheritedGetMethod();
639+
? indexer.GetOwnOrInheritedSetMethod()
640+
: indexer.GetOwnOrInheritedGetMethod();
641641
if (accessorForDefaultArguments is not null)
642642
{
643643
var argumentsBuilder = ArrayBuilder<BoundExpression>.GetInstance(accessorForDefaultArguments.ParameterCount);
@@ -664,7 +664,7 @@ private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundI
664664
}
665665

666666
BitVector defaultArguments = default;
667-
Debug.Assert(parameters.Length == indexerAccess.Indexer.Parameters.Length);
667+
Debug.Assert(parameters.Length == indexer.Parameters.Length);
668668

669669
ImmutableArray<string?> argumentNamesOpt = indexerAccess.ArgumentNamesOpt;
670670

@@ -690,9 +690,8 @@ private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundI
690690
}
691691
}
692692

693-
// Tracked by https://github.com/dotnet/roslyn/issues/78829 : caller info on extension parameter of an extension indexer will need the receiver/argument to be passed
694-
Debug.Assert(!indexerAccess.Indexer.IsExtensionBlockMember());
695-
BindDefaultArguments(indexerAccess.Syntax, parameters, extensionReceiver: null, argumentsBuilder, refKindsBuilderOpt, namesBuilder, ref argsToParams, out defaultArguments, indexerAccess.Expanded, enableCallerInfo: true, diagnostics: diagnostics);
693+
BoundExpression? extensionReceiver = indexer.IsExtensionBlockMember() ? indexerAccess.ReceiverOpt : null;
694+
BindDefaultArguments(indexerAccess.Syntax, parameters, extensionReceiver, argumentsBuilder, refKindsBuilderOpt, namesBuilder, ref argsToParams, out defaultArguments, indexerAccess.Expanded, enableCallerInfo: true, diagnostics: diagnostics);
696695

697696
if (namesBuilder is object)
698697
{
@@ -704,7 +703,7 @@ private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundI
704703
indexerAccess = indexerAccess.Update(
705704
indexerAccess.ReceiverOpt,
706705
indexerAccess.InitialBindingReceiverIsSubjectToCloning,
707-
indexerAccess.Indexer,
706+
indexer,
708707
argumentsBuilder.ToImmutableAndFree(),
709708
argumentNamesOpt,
710709
refKindsBuilderOpt?.ToImmutableOrNull() ?? default,

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,14 @@ internal static void ReportDiagnosticsIfDisallowedExtension(BindingDiagnosticBag
762762
}
763763
}
764764

765+
internal static void ReportDiagnosticsIfDisallowedExtensionIndexer(BindingDiagnosticBag diagnostics, PropertySymbol property, SyntaxNode syntax)
766+
{
767+
if (property.IsExtensionBlockMember())
768+
{
769+
MessageID.IDS_FeatureExtensionIndexers.CheckFeatureAvailability(diagnostics, syntax);
770+
}
771+
}
772+
765773
internal static void ReportDiagnosticsIfUnmanagedCallersOnly(BindingDiagnosticBag diagnostics, MethodSymbol symbol, SyntaxNodeOrToken syntax, bool isDelegateConversion)
766774
{
767775
var unmanagedCallersOnlyAttributeData = symbol.GetUnmanagedCallersOnlyAttributeData(forceComplete: false);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ private ImmutableArray<Symbol> BindExtensionMemberCref(ExtensionMemberCrefSyntax
242242
memberName = GetOperatorMethodName(operatorSyntax);
243243
parameters = operatorSyntax.Parameters;
244244
}
245+
// PROTOTYPE handle IndexerMemberCrefSyntax and check for LangVersion
245246

246247
if (memberName == null)
247248
{
@@ -326,7 +327,8 @@ ImmutableArray<Symbol> computeSortedAndFilteredCrefExtensionMembers(NamespaceOrT
326327

327328
foreach (var candidate in candidates)
328329
{
329-
if (!SourceMemberContainerTypeSymbol.IsAllowedExtensionMember(candidate))
330+
// PROTOTYPE we should find all the members supported in latest LangVer, but report if they require a new LangVer than current
331+
if (!SourceMemberContainerTypeSymbol.IsAllowedExtensionMember(candidate, LanguageVersion.Preview))
330332
{
331333
continue;
332334
}

0 commit comments

Comments
 (0)