From d8c97dcc8f92b53d5339a35cef91a09ed5bcb029 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 22 Jan 2025 15:21:40 -0800 Subject: [PATCH 1/6] Move merging of partial members to an earlier phase of members construction. Fixes #76651. Fixes #75002. Related to #76842. Related to #76870. --- .../Source/SourceMemberContainerSymbol.cs | 257 +++++++++++------- .../Semantics/PrimaryConstructorTests.cs | 70 +++-- .../Symbol/Symbols/PartialPropertiesTests.cs | 38 +++ 3 files changed, 245 insertions(+), 120 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index bb3ec749a0ffc..cc4b1f1613278 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1695,6 +1695,11 @@ internal void AssertMemberExposure(Symbol member, bool forDiagnostics = false) // Backing fields for field-like events are not added to the members list. member = e; } + else if (member is FieldSymbol { AssociatedSymbol: SourcePropertySymbolBase { PartialDefinitionPart: PropertySymbol definition } implementation } && + definition.PartialImplementationPart == (object)implementation && implementation.BackingField != (object)member) + { + member = implementation; // This is a workaround for https://github.com/dotnet/roslyn/issues/76870, remove once the issue is addressed. + } var membersAndInitializers = Volatile.Read(ref _lazyMembersAndInitializers); @@ -1716,7 +1721,7 @@ internal void AssertMemberExposure(Symbol member, bool forDiagnostics = false) if (declared is object) { - if (declared.NonTypeMembers.Contains(m => m == (object)member) || declared.PrimaryConstructor == (object)member) + if (declared.NonTypeMembersWithPartialImplementations.Contains(m => m == (object)member) || declared.PrimaryConstructor == (object)member) { return; } @@ -1738,6 +1743,16 @@ internal void AssertMemberExposure(Symbol member, bool forDiagnostics = false) static bool isMemberInCompleteMemberList(MembersAndInitializers? membersAndInitializers, Symbol member) { + switch (member) + { + case MethodSymbol method: + member = method.PartialDefinitionPart ?? method; + break; + case PropertySymbol property: + member = property.PartialDefinitionPart ?? property; + break; + } + return membersAndInitializers?.NonTypeMembers.Contains(m => m == (object)member) == true; } } @@ -1756,16 +1771,12 @@ private Dictionary, ImmutableArray> GetMembersByNam { if (_lazyMembersDictionary == null) { - var diagnostics = BindingDiagnosticBag.GetInstance(); - var membersDictionary = MakeAllMembers(diagnostics); + var membersDictionary = MakeAllMembers(); if (Interlocked.CompareExchange(ref _lazyMembersDictionary, membersDictionary, null) == null) { - AddDeclarationDiagnostics(diagnostics); state.NotePartComplete(CompletionPart.Members); } - - diagnostics.Free(); } state.SpinWaitComplete(CompletionPart.Members, default(CancellationToken)); @@ -2840,7 +2851,7 @@ private static bool ContainsModifier(SyntaxTokenList modifiers, SyntaxKind modif return false; } - private Dictionary, ImmutableArray> MakeAllMembers(BindingDiagnosticBag diagnostics) + private Dictionary, ImmutableArray> MakeAllMembers() { Dictionary, ImmutableArray> membersByName; var membersAndInitializers = GetMembersAndInitializers(); @@ -2860,8 +2871,6 @@ private Dictionary, ImmutableArray> MakeAllMembers( AddNestedTypesToDictionary(membersByName, GetTypeMembersDictionary()); } - MergePartialMembers(ref membersByName, diagnostics); - return membersByName; } @@ -2948,7 +2957,7 @@ public void Free() protected sealed class DeclaredMembersAndInitializers { - public readonly ImmutableArray NonTypeMembers; + public readonly ImmutableArray NonTypeMembersWithPartialImplementations; public readonly ImmutableArray> StaticInitializers; public readonly ImmutableArray> InstanceInitializers; public readonly bool HaveIndexers; @@ -2957,6 +2966,8 @@ protected sealed class DeclaredMembersAndInitializers public readonly bool IsNullableEnabledForInstanceConstructorsAndFields; public readonly bool IsNullableEnabledForStaticConstructorsAndFields; + private ImmutableArray _lazyNonTypeMembers; + public static readonly DeclaredMembersAndInitializers UninitializedSentinel = new DeclaredMembersAndInitializers(); private DeclaredMembersAndInitializers() @@ -2964,7 +2975,7 @@ private DeclaredMembersAndInitializers() } public DeclaredMembersAndInitializers( - ImmutableArray nonTypeMembers, + ImmutableArray nonTypeMembersWithPartialImplementations, ImmutableArray> staticInitializers, ImmutableArray> instanceInitializers, bool haveIndexers, @@ -2974,14 +2985,14 @@ public DeclaredMembersAndInitializers( bool isNullableEnabledForStaticConstructorsAndFields, CSharpCompilation compilation) { - Debug.Assert(!nonTypeMembers.IsDefault); + Debug.Assert(!nonTypeMembersWithPartialImplementations.IsDefault); AssertInitializers(staticInitializers, compilation); AssertInitializers(instanceInitializers, compilation); - Debug.Assert(!nonTypeMembers.Any(static s => s is TypeSymbol)); + Debug.Assert(!nonTypeMembersWithPartialImplementations.Any(static s => s is TypeSymbol)); Debug.Assert(declarationWithParameters is object == primaryConstructor is object); - this.NonTypeMembers = nonTypeMembers; + this.NonTypeMembersWithPartialImplementations = nonTypeMembersWithPartialImplementations; this.StaticInitializers = staticInitializers; this.InstanceInitializers = instanceInitializers; this.HaveIndexers = haveIndexers; @@ -3023,6 +3034,16 @@ public static void AssertInitializers(ImmutableArray GetNonTypeMembers(SourceMemberContainerTypeSymbol container) + { + if (_lazyNonTypeMembers.IsDefault) + { + container.MergePartialMembersAndInitializeNonTypeMembers(NonTypeMembersWithPartialImplementations, ref _lazyNonTypeMembers); + } + + return _lazyNonTypeMembers; + } } private sealed class MembersAndInitializersBuilder @@ -3040,9 +3061,9 @@ public MembersAndInitializersBuilder(DeclaredMembersAndInitializers declaredMemb this.IsNullableEnabledForStaticConstructorsAndFields = declaredMembersAndInitializers.IsNullableEnabledForStaticConstructorsAndFields; } - public MembersAndInitializers ToReadOnlyAndFree(DeclaredMembersAndInitializers declaredMembers) + public MembersAndInitializers ToReadOnlyAndFree(SourceMemberContainerTypeSymbol container, DeclaredMembersAndInitializers declaredMembers) { - var nonTypeMembers = NonTypeMembers?.ToImmutableAndFree() ?? declaredMembers.NonTypeMembers; + var nonTypeMembers = NonTypeMembers?.ToImmutableAndFree() ?? declaredMembers.GetNonTypeMembers(container); var instanceInitializers = InstanceInitializersForPositionalMembers is null ? declaredMembers.InstanceInitializers @@ -3136,17 +3157,18 @@ public void AddInstanceInitializerForPositionalMembers(FieldOrPropertyInitialize InstanceInitializersForPositionalMembers.Add(initializer); } - public IReadOnlyCollection GetNonTypeMembers(DeclaredMembersAndInitializers declaredMembers) + public IReadOnlyCollection GetNonTypeMembers(SourceMemberContainerTypeSymbol container, DeclaredMembersAndInitializers declaredMembers) { - return NonTypeMembers ?? (IReadOnlyCollection)declaredMembers.NonTypeMembers; + return NonTypeMembers ?? (IReadOnlyCollection)declaredMembers.GetNonTypeMembers(container); } - public void AddNonTypeMember(Symbol member, DeclaredMembersAndInitializers declaredMembers) + public void AddNonTypeMember(SourceMemberContainerTypeSymbol container, Symbol member, DeclaredMembersAndInitializers declaredMembers) { if (NonTypeMembers is null) { - NonTypeMembers = ArrayBuilder.GetInstance(declaredMembers.NonTypeMembers.Length + 1); - NonTypeMembers.AddRange(declaredMembers.NonTypeMembers); + var declaredNonTypeMembers = declaredMembers.GetNonTypeMembers(container); + NonTypeMembers = ArrayBuilder.GetInstance(declaredNonTypeMembers.Length + 1); + NonTypeMembers.AddRange(declaredNonTypeMembers); } NonTypeMembers.Add(member); @@ -3213,7 +3235,7 @@ public void Free() return null; } - return membersAndInitializersBuilder.ToReadOnlyAndFree(declaredMembersAndInitializers); + return membersAndInitializersBuilder.ToReadOnlyAndFree(this, declaredMembersAndInitializers); DeclaredMembersAndInitializers? getDeclaredMembersAndInitializers() { @@ -3287,6 +3309,43 @@ public void Free() } } + private void MergePartialMembersAndInitializeNonTypeMembers(ImmutableArray nonTypeMembersWithPartialImplementations, ref ImmutableArray nonTypeMembers) + { + PooledDictionary, object>? partialMembersToMerge = null; + + foreach (Symbol member in nonTypeMembersWithPartialImplementations) + { + if (member.IsPartialMember()) + { + ImmutableArrayExtensions.AddToMultiValueDictionaryBuilder( + partialMembersToMerge ??= s_nameToObjectPool.Allocate(), + (member.IsIndexer() ? WellKnownMemberNames.Indexer : member.Name).AsMemory(), + member); + } + } + + if (partialMembersToMerge is null) + { + ImmutableInterlocked.InterlockedInitialize(ref nonTypeMembers, nonTypeMembersWithPartialImplementations); + return; + } + + Debug.Assert(partialMembersToMerge.Count != 0); + + var diagnostics = BindingDiagnosticBag.GetInstance(); + var nonTypeMembersBuilder = ArrayBuilder.GetInstance(nonTypeMembersWithPartialImplementations.Length); + nonTypeMembersBuilder.AddRange(nonTypeMembersWithPartialImplementations); + MergePartialMembers(partialMembersToMerge, nonTypeMembersBuilder, diagnostics); + partialMembersToMerge.Free(); + + if (ImmutableInterlocked.InterlockedInitialize(ref nonTypeMembers, nonTypeMembersBuilder.ToImmutableAndFree())) + { + AddDeclarationDiagnostics(diagnostics); + } + + diagnostics.Free(); + } + internal ImmutableArray GetSimpleProgramEntryPoints() { @@ -3375,7 +3434,7 @@ internal IEnumerable GetMethodsPossiblyCapturingPrimar var declared = Volatile.Read(ref _lazyDeclaredMembersAndInitializers); if (declared is not null && declared != DeclaredMembersAndInitializers.UninitializedSentinel) { - nonTypeMembersToCheck = declared.NonTypeMembers; + nonTypeMembersToCheck = declared.GetNonTypeMembers(this); primaryConstructor = declared.PrimaryConstructor; } else @@ -3421,7 +3480,7 @@ internal ImmutableArray GetMembersToMatchAgainstDeclarationSpan() if (declared is not null && declared != DeclaredMembersAndInitializers.UninitializedSentinel) { Debug.Assert(declared.PrimaryConstructor is not null); - return declared.NonTypeMembers; + return declared.GetNonTypeMembers(this); } else { @@ -3445,7 +3504,7 @@ internal ImmutableArray GetCandidateMembersForLookup(string name) var declared = Volatile.Read(ref _lazyDeclaredMembersAndInitializers); if (declared is not null && declared != DeclaredMembersAndInitializers.UninitializedSentinel) { - nonTypeMembersToCheck = declared.NonTypeMembers; + nonTypeMembersToCheck = declared.GetNonTypeMembers(this); primaryConstructor = declared.PrimaryConstructor; } else @@ -3609,52 +3668,57 @@ internal Binder GetBinder(CSharpSyntaxNode syntaxNode) } private void MergePartialMembers( - ref Dictionary, ImmutableArray> membersByName, + Dictionary, object> membersByName, + ArrayBuilder nonTypeMembers, BindingDiagnosticBag diagnostics) { - var memberNames = ArrayBuilder>.GetInstance(membersByName.Count); - memberNames.AddRange(membersByName.Keys); - //key and value will be the same object var membersBySignature = new Dictionary(MemberSignatureComparer.PartialMethodsComparer); - foreach (var name in memberNames) + foreach (var pair in membersByName) { membersBySignature.Clear(); - foreach (var symbol in membersByName[name]) - { - if (!symbol.IsPartialMember()) - { - continue; - } - - if (!membersBySignature.TryGetValue(symbol, out var prev)) - { - membersBySignature.Add(symbol, symbol); - continue; - } - switch (symbol, prev) + if (pair.Value is ArrayBuilder arrayBuilder) + { + foreach (var symbol in arrayBuilder) { - case (SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod): - mergePartialMethods(ref membersByName, name, currentMethod, prevMethod, diagnostics); - break; + Debug.Assert(symbol.IsPartialMember()); - case (SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty): - mergePartialProperties(ref membersByName, name, currentProperty, prevProperty, diagnostics); - break; - - case (SourcePropertyAccessorSymbol, SourcePropertyAccessorSymbol): - break; // accessor symbols and their diagnostics are handled by processing the associated property + if (!membersBySignature.TryGetValue(symbol, out var prev)) + { + membersBySignature.Add(symbol, symbol); + continue; + } - default: - // This is an error scenario. We simply don't merge the symbols in this case and a duplicate name diagnostic is reported separately. - // One way this case can be reached is if type contains both `public partial int P { get; }` and `public partial int P_get();`. - Debug.Assert(symbol is SourceOrdinaryMethodSymbol or SourcePropertySymbol or SourcePropertyAccessorSymbol); - Debug.Assert(prev is SourceOrdinaryMethodSymbol or SourcePropertySymbol or SourcePropertyAccessorSymbol); - break; + switch (symbol, prev) + { + case (SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod): + mergePartialMethods(nonTypeMembers, currentMethod, prevMethod, diagnostics); + break; + + case (SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty): + mergePartialProperties(nonTypeMembers, currentProperty, prevProperty, diagnostics); + break; + + case (SourcePropertyAccessorSymbol, SourcePropertyAccessorSymbol): + break; // accessor symbols and their diagnostics are handled by processing the associated property + + default: + // This is an error scenario. We simply don't merge the symbols in this case and a duplicate name diagnostic is reported separately. + // One way this case can be reached is if type contains both `public partial int P { get; }` and `public partial int P_get();`. + Debug.Assert(symbol is SourceOrdinaryMethodSymbol or SourcePropertySymbol or SourcePropertyAccessorSymbol); + Debug.Assert(prev is SourceOrdinaryMethodSymbol or SourcePropertySymbol or SourcePropertyAccessorSymbol); + break; + } } } + else + { + var symbol = (Symbol)pair.Value; + Debug.Assert(symbol.IsPartialMember()); + membersBySignature.Add(symbol, symbol); + } foreach (var symbol in membersBySignature.Values) { @@ -3691,9 +3755,7 @@ private void MergePartialMembers( } } - memberNames.Free(); - - void mergePartialMethods(ref Dictionary, ImmutableArray> membersByName, ReadOnlyMemory name, SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod, BindingDiagnosticBag diagnostics) + void mergePartialMethods(ArrayBuilder nonTypeMembers, SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod, BindingDiagnosticBag diagnostics) { if (currentMethod.IsPartialImplementation && (prevMethod.IsPartialImplementation || (prevMethod.OtherPartOfPartial is MethodSymbol otherImplementation && (object)otherImplementation != currentMethod))) @@ -3709,12 +3771,11 @@ void mergePartialMethods(ref Dictionary, ImmutableArray, ImmutableArray> membersByName, ReadOnlyMemory name, SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty, BindingDiagnosticBag diagnostics) + void mergePartialProperties(ArrayBuilder nonTypeMembers, SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty, BindingDiagnosticBag diagnostics) { if (currentProperty.IsPartialImplementation && (prevProperty.IsPartialImplementation || (prevProperty.OtherPartOfPartial is SourcePropertySymbol otherImplementation && (object)otherImplementation != currentProperty))) @@ -3733,19 +3794,17 @@ void mergePartialProperties(ref Dictionary, ImmutableArray< diagnostics.Add(ErrorCode.ERR_PartialPropertyDuplicateInitializer, currentProperty.GetFirstLocation()); } - DuplicateMembersByNameIfCached(ref membersByName); - mergeAccessors(ref membersByName, (SourcePropertyAccessorSymbol?)currentProperty.GetMethod, (SourcePropertyAccessorSymbol?)prevProperty.GetMethod); - mergeAccessors(ref membersByName, (SourcePropertyAccessorSymbol?)currentProperty.SetMethod, (SourcePropertyAccessorSymbol?)prevProperty.SetMethod); - FixPartialProperty(ref membersByName, name, prevProperty, currentProperty); + mergeAccessors(nonTypeMembers, (SourcePropertyAccessorSymbol?)currentProperty.GetMethod, (SourcePropertyAccessorSymbol?)prevProperty.GetMethod); + mergeAccessors(nonTypeMembers, (SourcePropertyAccessorSymbol?)currentProperty.SetMethod, (SourcePropertyAccessorSymbol?)prevProperty.SetMethod); + FixPartialProperty(nonTypeMembers, prevProperty, currentProperty); } - void mergeAccessors(ref Dictionary, ImmutableArray> membersByName, SourcePropertyAccessorSymbol? currentAccessor, SourcePropertyAccessorSymbol? prevAccessor) + void mergeAccessors(ArrayBuilder nonTypeMembers, SourcePropertyAccessorSymbol? currentAccessor, SourcePropertyAccessorSymbol? prevAccessor) { if (currentAccessor is { } && prevAccessor is { }) { - var name = currentAccessor.Name.AsMemory(); var implementationAccessor = currentProperty.IsPartialDefinition ? prevAccessor : currentAccessor; - membersByName[name] = Remove(membersByName[name], implementationAccessor); + Remove(nonTypeMembers, implementationAccessor); } else if (currentAccessor is { } || prevAccessor is { }) { @@ -3766,17 +3825,8 @@ static bool hasInitializer(SourcePropertySymbol property) } } - private void DuplicateMembersByNameIfCached(ref Dictionary, ImmutableArray> membersByName) - { - if ((object)membersByName == _lazyEarlyAttributeDecodingMembersDictionary) - { - // Avoid mutating the cached dictionary and especially avoid doing this possibly on multiple threads in parallel. - membersByName = new Dictionary, ImmutableArray>(membersByName, ReadOnlyMemoryOfCharComparer.Instance); - } - } - - /// Links together the definition and implementation parts of a partial method. Returns a member list which has the implementation part removed. - private static ImmutableArray FixPartialMethod(ImmutableArray symbols, SourceOrdinaryMethodSymbol part1, SourceOrdinaryMethodSymbol part2) + /// Links together the definition and implementation parts of a partial method. Removes implementation part from . + private static void FixPartialMethod(ArrayBuilder nonTypeMembers, SourceOrdinaryMethodSymbol part1, SourceOrdinaryMethodSymbol part2) { SourceOrdinaryMethodSymbol definition; SourceOrdinaryMethodSymbol implementation; @@ -3794,11 +3844,11 @@ private static ImmutableArray FixPartialMethod(ImmutableArray sy SourceOrdinaryMethodSymbol.InitializePartialMethodParts(definition, implementation); // a partial method is represented in the member list by its definition part: - return Remove(symbols, implementation); + Remove(nonTypeMembers, implementation); } - /// Links together the definition and implementation parts of a partial property. Returns a member list which has the implementation part removed. - private static void FixPartialProperty(ref Dictionary, ImmutableArray> membersByName, ReadOnlyMemory name, SourcePropertySymbol part1, SourcePropertySymbol part2) + /// Links together the definition and implementation parts of a partial property. Removes implementation part from + private static void FixPartialProperty(ArrayBuilder nonTypeMembers, SourcePropertySymbol part1, SourcePropertySymbol part2) { SourcePropertySymbol definition; SourcePropertySymbol implementation; @@ -3816,27 +3866,28 @@ private static void FixPartialProperty(ref Dictionary, Immu if (implementation.DeclaredBackingField is { } implementationField && definition.DeclaredBackingField is { }) { - var fieldName = implementationField.Name.AsMemory(); - membersByName[fieldName] = Remove(membersByName[fieldName], implementationField); + Remove(nonTypeMembers, implementationField); } SourcePropertySymbol.InitializePartialPropertyParts(definition, implementation); // a partial property is represented in the member list by its definition part: - membersByName[name] = Remove(membersByName[name], implementation); + Remove(nonTypeMembers, implementation); } - private static ImmutableArray Remove(ImmutableArray symbols, Symbol symbol) + private static void Remove(ArrayBuilder symbols, Symbol symbol) { - var builder = ArrayBuilder.GetInstance(); - foreach (var s in symbols) + for (int i = 0; i < symbols.Count; i++) { - if (!ReferenceEquals(s, symbol)) + Symbol s = symbols[i]; + if (ReferenceEquals(s, symbol)) { - builder.Add(s); + symbols.RemoveAt(i); + return; } } - return builder.ToImmutableAndFree(); + + throw ExceptionUtilities.Unreachable(); } /// @@ -4166,7 +4217,7 @@ private void AddSynthesizedSimpleProgramEntryPointIfNecessary(MembersAndInitiali var simpleProgramEntryPoints = GetSimpleProgramEntryPoints(); foreach (var member in simpleProgramEntryPoints) { - builder.AddNonTypeMember(member, declaredMembersAndInitializers); + builder.AddNonTypeMember(this, member, declaredMembersAndInitializers); } } @@ -4177,7 +4228,7 @@ private void AddSynthesizedTypeMembersIfNecessary(MembersAndInitializersBuilder return; } - var membersSoFar = builder.GetNonTypeMembers(declaredMembersAndInitializers); + var membersSoFar = builder.GetNonTypeMembers(this, declaredMembersAndInitializers); var members = ArrayBuilder.GetInstance(membersSoFar.Count + 1); if (declaration.Kind is not (DeclarationKind.Record or DeclarationKind.RecordStruct)) @@ -4805,7 +4856,7 @@ private void AddSynthesizedConstructorsIfNecessary(MembersAndInitializersBuilder // CONSIDER: if this traversal becomes a bottleneck, the flags could be made outputs of the // dictionary construction process. For now, this is more encapsulated. - var membersSoFar = builder.GetNonTypeMembers(declaredMembersAndInitializers); + var membersSoFar = builder.GetNonTypeMembers(this, declaredMembersAndInitializers); foreach (var member in membersSoFar) { if (member.Kind == SymbolKind.Method) @@ -4844,7 +4895,7 @@ private void AddSynthesizedConstructorsIfNecessary(MembersAndInitializersBuilder if ((!hasParameterlessInstanceConstructor && this.IsStructType()) || (!hasInstanceConstructor && !this.IsStatic && !this.IsInterface)) { - builder.AddNonTypeMember((this.TypeKind == TypeKind.Submission) ? + builder.AddNonTypeMember(this, (this.TypeKind == TypeKind.Submission) ? new SynthesizedSubmissionConstructor(this, diagnostics) : new SynthesizedInstanceConstructor(this), declaredMembersAndInitializers); @@ -4858,15 +4909,15 @@ private void AddSynthesizedConstructorsIfNecessary(MembersAndInitializersBuilder { // Note: we don't have to put anything in the method - the binder will // do that when processing field initializers. - builder.AddNonTypeMember(new SynthesizedStaticConstructor(this), declaredMembersAndInitializers); + builder.AddNonTypeMember(this, new SynthesizedStaticConstructor(this), declaredMembersAndInitializers); } if (this.IsScriptClass) { var scriptInitializer = new SynthesizedInteractiveInitializerMethod(this, diagnostics); - builder.AddNonTypeMember(scriptInitializer, declaredMembersAndInitializers); + builder.AddNonTypeMember(this, scriptInitializer, declaredMembersAndInitializers); var scriptEntryPoint = SynthesizedEntryPointSymbol.Create(scriptInitializer, diagnostics); - builder.AddNonTypeMember(scriptEntryPoint, declaredMembersAndInitializers); + builder.AddNonTypeMember(this, scriptEntryPoint, declaredMembersAndInitializers); } static bool hasNonConstantInitializer(ImmutableArray> initializers) @@ -4882,7 +4933,7 @@ private void AddSynthesizedTupleMembersIfNecessary(MembersAndInitializersBuilder return; } - var synthesizedMembers = this.MakeSynthesizedTupleMembers(declaredMembersAndInitializers.NonTypeMembers); + var synthesizedMembers = this.MakeSynthesizedTupleMembers(declaredMembersAndInitializers.GetNonTypeMembers(this)); if (synthesizedMembers is null) { return; @@ -4890,7 +4941,7 @@ private void AddSynthesizedTupleMembersIfNecessary(MembersAndInitializersBuilder foreach (var synthesizedMember in synthesizedMembers) { - builder.AddNonTypeMember(synthesizedMember, declaredMembersAndInitializers); + builder.AddNonTypeMember(this, synthesizedMember, declaredMembersAndInitializers); } synthesizedMembers.Free(); diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs index 623a2f0f15f6b..b6c2778c94988 100644 --- a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs +++ b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs @@ -19791,6 +19791,7 @@ class C(int p) } [WorkItem("https://github.com/dotnet/roslyn/issues/75002")] + [WorkItem("https://github.com/dotnet/roslyn/issues/76651")] [Fact] public void PartialMembers_01() { @@ -19812,14 +19813,49 @@ public partial void M() { } var comp = CreateCompilation([source1, source2]); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); - // https://github.com/dotnet/roslyn/issues/75002: SemanticModel.GetDiagnostics() does not merge partial members. + model.GetDiagnostics().Verify(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76651")] + public void PartialMembers_02() + { + var source1 = """ +[System.Diagnostics.CodeAnalysis.Experimental(C.P)] +class Repro +{ +} +"""; + + var source2 = """ +partial class C +{ + public static partial string P {get=>"";set{}} + public static partial string P {get;set;} +} + +namespace System.Diagnostics.CodeAnalysis +{ + [AttributeUsage(AttributeTargets.All, Inherited = false)] + public sealed class ExperimentalAttribute : Attribute + { + public ExperimentalAttribute(string diagnosticId) { } + + public string UrlFormat { get; set; } + + public string Message { get; set; } + } +} +"""; + var comp = CreateCompilation([source1, source2]); + + var tree = comp.SyntaxTrees[0]; + var model = comp.GetSemanticModel(tree, ignoreAccessibility: false); + model.GetDiagnostics().Verify( - // (2,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()' - // c.M(); - Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(2, 3), - // (3,7): error CS0229: Ambiguity between 'C.P' and 'C.P' - // _ = c.P; - Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(3, 7)); + // (1,47): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type + // [System.Diagnostics.CodeAnalysis.Experimental(C.P)] + Diagnostic(ErrorCode.ERR_BadAttributeArgument, "C.P").WithLocation(1, 47) + ); } [Fact] @@ -19880,14 +19916,14 @@ partial class C(int p) var comp = CreateCompilation([source1, source2], targetFramework: TargetFramework.Net80); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); - // https://github.com/dotnet/roslyn/issues/75002: SemanticModel.GetDiagnostics() does not merge partial members. model.GetDiagnostics().Verify( - // (4,7): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()' + // (4,5): warning CS8600: Converting null literal or possible null value to non-nullable type. // o = c.M(); - Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(4, 7), - // (5,7): error CS0229: Ambiguity between 'C.P' and 'C.P' + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "c.M()").WithLocation(4, 5), + // (5,5): warning CS8600: Converting null literal or possible null value to non-nullable type. // o = c.P; - Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(5, 7)); + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "c.P").WithLocation(5, 5) + ); } [WorkItem("https://github.com/dotnet/roslyn/issues/75002")] @@ -19916,14 +19952,14 @@ partial class C(int p) var comp = CreateCompilation([source1, source2], targetFramework: TargetFramework.Net80); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); - // https://github.com/dotnet/roslyn/issues/75002: SemanticModel.GetDiagnostics() does not merge partial members. model.GetDiagnostics().Verify( - // (4,7): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()' + // (4,5): warning CS8600: Converting null literal or possible null value to non-nullable type. // o = c.M(); - Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(4, 7), - // (5,7): error CS0229: Ambiguity between 'C.P' and 'C.P' + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "c.M()").WithLocation(4, 5), + // (5,5): warning CS8600: Converting null literal or possible null value to non-nullable type. // o = c.P; - Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(5, 7)); + Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "c.P").WithLocation(5, 5) + ); } [Fact] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/PartialPropertiesTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/PartialPropertiesTests.cs index eaa4ca1a170a9..6673e386e5806 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/PartialPropertiesTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/PartialPropertiesTests.cs @@ -5090,5 +5090,43 @@ partial struct S var comp = CreateCompilation(source); comp.VerifyEmitDiagnostics(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76842")] + public void IndexerWithName_01() + { + var source = """ + using System.Runtime.CompilerServices; + + partial struct S1 + { + public partial int this[int x] {get=>x;} + + [IndexerName("MyName")] + public partial int this[int x] {get;} + } + """; + + var comp = CreateCompilation(source); + comp.VerifyEmitDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76842")] + public void IndexerWithName_02() + { + var source = """ + using System.Runtime.CompilerServices; + + partial struct S1 + { + [IndexerName("MyName")] + public partial int this[int x] {get=>x;} + + public partial int this[int x] {get;} + } + """; + + var comp = CreateCompilation(source); + comp.VerifyEmitDiagnostics(); + } } } From db8cef47eb2a7df5c685353a9e2477f4c1284c79 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Wed, 22 Jan 2025 17:02:17 -0800 Subject: [PATCH 2/6] Additional fixup --- .../Source/SourceMemberContainerSymbol.cs | 24 +++++++++++++++++++ .../Source/SourcePropertySymbolBase.cs | 23 +++++++----------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index cc4b1f1613278..34d23505a92d8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -3755,6 +3755,30 @@ private void MergePartialMembers( } } + foreach (var pair in membersByName) + { + if (pair.Value is ArrayBuilder arrayBuilder) + { + foreach (var symbol in arrayBuilder) + { + fixupNotMergedPartialProperty(symbol); + } + } + else + { + fixupNotMergedPartialProperty((Symbol)pair.Value); + } + } + + static void fixupNotMergedPartialProperty(Symbol symbol) + { + Debug.Assert(symbol.IsPartialMember()); + if (symbol is SourcePropertySymbol { OtherPartOfPartial: null } property) + { + property.SetMergedBackingField(property.DeclaredBackingField); + } + } + void mergePartialMethods(ArrayBuilder nonTypeMembers, SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod, BindingDiagnosticBag diagnostics) { if (currentMethod.IsPartialImplementation && diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index ddb22a7995cba..d3fa761b0baee 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using System.Globalization; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Emit; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -74,7 +75,7 @@ private enum Flags : ushort #nullable enable private SynthesizedBackingFieldSymbol? _lazyDeclaredBackingField; - private SynthesizedBackingFieldSymbol? _lazyMergedBackingField; + private StrongBox? _lazyMergedBackingField; protected SourcePropertySymbolBase( SourceMemberContainerTypeSymbol containingType, @@ -756,19 +757,11 @@ internal SynthesizedBackingFieldSymbol BackingField if (_lazyMergedBackingField is null) { var backingField = DeclaredBackingField; - // The property should only be used after members in the containing - // type are complete, and partial members have been merged. - if (!_containingType.AreMembersComplete) - { - // When calling through the SemanticModel, partial members are not - // necessarily merged when the containing type includes a primary - // constructor - see https://github.com/dotnet/roslyn/issues/75002. - Debug.Assert(_containingType.PrimaryConstructor is { }); - return backingField; - } - Interlocked.CompareExchange(ref _lazyMergedBackingField, backingField, null); + // The property should only be used after partial members have been merged. + Debug.Assert(!IsPartial); + Interlocked.CompareExchange(ref _lazyMergedBackingField, new StrongBox(backingField), null); } - return _lazyMergedBackingField; + return _lazyMergedBackingField.Value; } } @@ -787,8 +780,8 @@ internal SynthesizedBackingFieldSymbol? DeclaredBackingField internal void SetMergedBackingField(SynthesizedBackingFieldSymbol? backingField) { - Interlocked.CompareExchange(ref _lazyMergedBackingField, backingField, null); - Debug.Assert((object?)_lazyMergedBackingField == backingField); + Interlocked.CompareExchange(ref _lazyMergedBackingField, new StrongBox(backingField), null); + Debug.Assert((object?)_lazyMergedBackingField.Value == backingField); } private SynthesizedBackingFieldSymbol CreateBackingField() From fe24292f23e34caa357ccba44270b5f3028aac07 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Thu, 23 Jan 2025 17:40:37 -0800 Subject: [PATCH 3/6] Make methods static --- .../Portable/Symbols/Source/SourceMemberContainerSymbol.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 34d23505a92d8..18b343031917c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -3667,7 +3667,7 @@ internal Binder GetBinder(CSharpSyntaxNode syntaxNode) return this.DeclaringCompilation.GetBinder(syntaxNode); } - private void MergePartialMembers( + private static void MergePartialMembers( Dictionary, object> membersByName, ArrayBuilder nonTypeMembers, BindingDiagnosticBag diagnostics) @@ -3779,7 +3779,7 @@ static void fixupNotMergedPartialProperty(Symbol symbol) } } - void mergePartialMethods(ArrayBuilder nonTypeMembers, SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod, BindingDiagnosticBag diagnostics) + static void mergePartialMethods(ArrayBuilder nonTypeMembers, SourceOrdinaryMethodSymbol currentMethod, SourceOrdinaryMethodSymbol prevMethod, BindingDiagnosticBag diagnostics) { if (currentMethod.IsPartialImplementation && (prevMethod.IsPartialImplementation || (prevMethod.OtherPartOfPartial is MethodSymbol otherImplementation && (object)otherImplementation != currentMethod))) @@ -3799,7 +3799,7 @@ void mergePartialMethods(ArrayBuilder nonTypeMembers, SourceOrdinaryMeth } } - void mergePartialProperties(ArrayBuilder nonTypeMembers, SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty, BindingDiagnosticBag diagnostics) + static void mergePartialProperties(ArrayBuilder nonTypeMembers, SourcePropertySymbol currentProperty, SourcePropertySymbol prevProperty, BindingDiagnosticBag diagnostics) { if (currentProperty.IsPartialImplementation && (prevProperty.IsPartialImplementation || (prevProperty.OtherPartOfPartial is SourcePropertySymbol otherImplementation && (object)otherImplementation != currentProperty))) From 63ff31db945803e009a3ed40d2d6eb0eeb149d90 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Fri, 24 Jan 2025 16:40:28 -0800 Subject: [PATCH 4/6] Rename --- .../Source/SourceMemberContainerSymbol.cs | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 18b343031917c..abb58e2d51de5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -2896,7 +2896,7 @@ private static void AddNestedTypesToDictionary( private sealed class DeclaredMembersAndInitializersBuilder { - public ArrayBuilder NonTypeMembers = ArrayBuilder.GetInstance(); + public ArrayBuilder NonTypeMembersWithPartialImplementations = ArrayBuilder.GetInstance(); public readonly ArrayBuilder> StaticInitializers = ArrayBuilder>.GetInstance(); public readonly ArrayBuilder> InstanceInitializers = ArrayBuilder>.GetInstance(); public bool HaveIndexers; @@ -2909,7 +2909,7 @@ private sealed class DeclaredMembersAndInitializersBuilder public DeclaredMembersAndInitializers ToReadOnlyAndFree(CSharpCompilation compilation) { return new DeclaredMembersAndInitializers( - NonTypeMembers.ToImmutableAndFree(), + NonTypeMembersWithPartialImplementations.ToImmutableAndFree(), MembersAndInitializersBuilder.ToReadOnlyAndFree(StaticInitializers), MembersAndInitializersBuilder.ToReadOnlyAndFree(InstanceInitializers), HaveIndexers, @@ -2939,7 +2939,7 @@ private ref bool GetIsNullableEnabledForConstructorsAndFields(bool useStatic) public void Free() { - NonTypeMembers.Free(); + NonTypeMembersWithPartialImplementations.Free(); foreach (var group in StaticInitializers) { @@ -3281,11 +3281,11 @@ public void Free() { case TypeKind.Struct: CheckForStructBadInitializers(builder, diagnostics); - CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: false, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: false, diagnostics: diagnostics); break; case TypeKind.Enum: - CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: true, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: true, diagnostics: diagnostics); break; case TypeKind.Class: @@ -3596,7 +3596,7 @@ private void AddDeclaredNontypeMembers(DeclaredMembersAndInitializersBuilder bui break; case SyntaxKind.DelegateDeclaration: - SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembers, (DelegateDeclarationSyntax)syntax, diagnostics); + SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembersWithPartialImplementations, (DelegateDeclarationSyntax)syntax, diagnostics); break; case SyntaxKind.NamespaceDeclaration: @@ -4083,7 +4083,7 @@ private void AddEnumMembers(DeclaredMembersAndInitializersBuilder result, EnumDe symbol = SourceEnumConstantSymbol.CreateImplicitValuedConstant(this, member, otherSymbol, otherSymbolOffset, diagnostics); } - result.NonTypeMembers.Add(symbol); + result.NonTypeMembersWithPartialImplementations.Add(symbol); if (valueOpt != null || otherSymbol is null) { @@ -4230,7 +4230,7 @@ private void CheckForStructBadInitializers(DeclaredMembersAndInitializersBuilder } } - if (hasInitializers && !builder.NonTypeMembers.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) + if (hasInitializers && !builder.NonTypeMembersWithPartialImplementations.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) { diagnostics.Add(ErrorCode.ERR_StructHasInitializersAndNoDeclaredConstructor, GetFirstLocation()); } @@ -5020,7 +5020,7 @@ private void AddNonTypeMembers( var fieldSymbol = (modifiers & DeclarationModifiers.Fixed) == 0 ? new SourceMemberFieldSymbolFromDeclarator(this, variable, modifiers, modifierErrors, diagnostics) : new SourceFixedFieldSymbol(this, variable, modifiers, modifierErrors, diagnostics); - builder.NonTypeMembers.Add(fieldSymbol); + builder.NonTypeMembersWithPartialImplementations.Add(fieldSymbol); // All fields are included in the nullable context for constructors and initializers, even fields without // initializers, to ensure warnings are reported for uninitialized non-nullable fields in NullableWalker. builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: fieldSymbol.IsStatic, compilation, variable); @@ -5028,7 +5028,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, variable, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, variable, this, DeclarationModifiers.Private | (modifiers & DeclarationModifiers.Static), fieldSymbol); } @@ -5058,7 +5058,7 @@ private void AddNonTypeMembers( } var method = SourceOrdinaryMethodSymbol.CreateMethodSymbol(this, bodyBinder, methodSyntax, compilation.IsNullableAnalysisEnabledIn(methodSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5073,7 +5073,7 @@ private void AddNonTypeMembers( bool isNullableEnabled = compilation.IsNullableAnalysisEnabledIn(constructorSyntax); var constructor = SourceConstructorSymbol.CreateConstructorSymbol(this, constructorSyntax, isNullableEnabled, diagnostics); - builder.NonTypeMembers.Add(constructor); + builder.NonTypeMembersWithPartialImplementations.Add(constructor); if (constructorSyntax.Initializer?.Kind() != SyntaxKind.ThisConstructorInitializer) { builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: constructor.IsStatic, isNullableEnabled); @@ -5095,7 +5095,7 @@ private void AddNonTypeMembers( // when it is loaded from metadata. Perhaps we should just treat it as an Ordinary // method in such cases? var destructor = new SourceDestructorSymbol(this, destructorSyntax, compilation.IsNullableAnalysisEnabledIn(destructorSyntax), diagnostics); - builder.NonTypeMembers.Add(destructor); + builder.NonTypeMembersWithPartialImplementations.Add(destructor); } break; @@ -5109,10 +5109,10 @@ private void AddNonTypeMembers( } var property = SourcePropertySymbol.Create(this, bodyBinder, propertySyntax, diagnostics); - builder.NonTypeMembers.Add(property); + builder.NonTypeMembersWithPartialImplementations.Add(property); - AddAccessorIfAvailable(builder.NonTypeMembers, property.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, property.SetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.SetMethod); FieldSymbol? backingField = property.DeclaredBackingField; // TODO: can we leave this out of the member list? @@ -5121,7 +5121,7 @@ private void AddNonTypeMembers( // a similar manner and make the autoproperty fields private. if (backingField is { }) { - builder.NonTypeMembers.Add(backingField); + builder.NonTypeMembersWithPartialImplementations.Add(backingField); builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: backingField.IsStatic, compilation, propertySyntax); var initializer = propertySyntax.Initializer; @@ -5130,7 +5130,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the initializer - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, initializer, this, DeclarationModifiers.Private | (property.IsStatic ? DeclarationModifiers.Static : 0), @@ -5163,14 +5163,14 @@ private void AddNonTypeMembers( foreach (VariableDeclaratorSyntax declarator in eventFieldSyntax.Declaration.Variables) { SourceFieldLikeEventSymbol @event = new SourceFieldLikeEventSymbol(this, bodyBinder, eventFieldSyntax.Modifiers, declarator, diagnostics); - builder.NonTypeMembers.Add(@event); + builder.NonTypeMembersWithPartialImplementations.Add(@event); FieldSymbol? associatedField = @event.AssociatedField; if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, declarator, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, declarator, this, DeclarationModifiers.Private | (@event.IsStatic ? DeclarationModifiers.Static : 0), associatedField); } @@ -5198,8 +5198,8 @@ private void AddNonTypeMembers( Debug.Assert((object)@event.AddMethod != null); Debug.Assert((object)@event.RemoveMethod != null); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); } } break; @@ -5215,10 +5215,10 @@ private void AddNonTypeMembers( var @event = new SourceCustomEventSymbol(this, bodyBinder, eventSyntax, diagnostics); - builder.NonTypeMembers.Add(@event); + builder.NonTypeMembersWithPartialImplementations.Add(@event); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); Debug.Assert(@event.AssociatedField is null); } @@ -5235,9 +5235,9 @@ private void AddNonTypeMembers( var indexer = SourcePropertySymbol.Create(this, bodyBinder, indexerSyntax, diagnostics); builder.HaveIndexers = true; - builder.NonTypeMembers.Add(indexer); - AddAccessorIfAvailable(builder.NonTypeMembers, indexer.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, indexer.SetMethod); + builder.NonTypeMembersWithPartialImplementations.Add(indexer); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.SetMethod); } break; @@ -5252,7 +5252,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedConversionSymbol.CreateUserDefinedConversionSymbol( this, bodyBinder, conversionOperatorSyntax, compilation.IsNullableAnalysisEnabledIn(conversionOperatorSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5267,7 +5267,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedOperatorSymbol.CreateUserDefinedOperatorSymbol( this, bodyBinder, operatorSyntax, compilation.IsNullableAnalysisEnabledIn(operatorSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5294,7 +5294,7 @@ private void AddNonTypeMembers( foreach (var vdecl in decl.Declaration.Variables) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, vdecl, this, DeclarationModifiers.Private, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, vdecl, this, DeclarationModifiers.Private, containingFieldOpt: null); } break; @@ -5306,7 +5306,7 @@ private void AddNonTypeMembers( case SyntaxKind.ThrowStatement: case SyntaxKind.SwitchStatement: case SyntaxKind.LockStatement: - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, innerStatement, this, DeclarationModifiers.Private, From e3d22829d832ccf266ce089b6e48751add4a3981 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Sat, 25 Jan 2025 14:39:09 -0800 Subject: [PATCH 5/6] Revert "Rename" Revert the rename. --- .../Source/SourceMemberContainerSymbol.cs | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index abb58e2d51de5..18b343031917c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -2896,7 +2896,7 @@ private static void AddNestedTypesToDictionary( private sealed class DeclaredMembersAndInitializersBuilder { - public ArrayBuilder NonTypeMembersWithPartialImplementations = ArrayBuilder.GetInstance(); + public ArrayBuilder NonTypeMembers = ArrayBuilder.GetInstance(); public readonly ArrayBuilder> StaticInitializers = ArrayBuilder>.GetInstance(); public readonly ArrayBuilder> InstanceInitializers = ArrayBuilder>.GetInstance(); public bool HaveIndexers; @@ -2909,7 +2909,7 @@ private sealed class DeclaredMembersAndInitializersBuilder public DeclaredMembersAndInitializers ToReadOnlyAndFree(CSharpCompilation compilation) { return new DeclaredMembersAndInitializers( - NonTypeMembersWithPartialImplementations.ToImmutableAndFree(), + NonTypeMembers.ToImmutableAndFree(), MembersAndInitializersBuilder.ToReadOnlyAndFree(StaticInitializers), MembersAndInitializersBuilder.ToReadOnlyAndFree(InstanceInitializers), HaveIndexers, @@ -2939,7 +2939,7 @@ private ref bool GetIsNullableEnabledForConstructorsAndFields(bool useStatic) public void Free() { - NonTypeMembersWithPartialImplementations.Free(); + NonTypeMembers.Free(); foreach (var group in StaticInitializers) { @@ -3281,11 +3281,11 @@ public void Free() { case TypeKind.Struct: CheckForStructBadInitializers(builder, diagnostics); - CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: false, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: false, diagnostics: diagnostics); break; case TypeKind.Enum: - CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: true, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: true, diagnostics: diagnostics); break; case TypeKind.Class: @@ -3596,7 +3596,7 @@ private void AddDeclaredNontypeMembers(DeclaredMembersAndInitializersBuilder bui break; case SyntaxKind.DelegateDeclaration: - SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembersWithPartialImplementations, (DelegateDeclarationSyntax)syntax, diagnostics); + SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembers, (DelegateDeclarationSyntax)syntax, diagnostics); break; case SyntaxKind.NamespaceDeclaration: @@ -4083,7 +4083,7 @@ private void AddEnumMembers(DeclaredMembersAndInitializersBuilder result, EnumDe symbol = SourceEnumConstantSymbol.CreateImplicitValuedConstant(this, member, otherSymbol, otherSymbolOffset, diagnostics); } - result.NonTypeMembersWithPartialImplementations.Add(symbol); + result.NonTypeMembers.Add(symbol); if (valueOpt != null || otherSymbol is null) { @@ -4230,7 +4230,7 @@ private void CheckForStructBadInitializers(DeclaredMembersAndInitializersBuilder } } - if (hasInitializers && !builder.NonTypeMembersWithPartialImplementations.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) + if (hasInitializers && !builder.NonTypeMembers.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) { diagnostics.Add(ErrorCode.ERR_StructHasInitializersAndNoDeclaredConstructor, GetFirstLocation()); } @@ -5020,7 +5020,7 @@ private void AddNonTypeMembers( var fieldSymbol = (modifiers & DeclarationModifiers.Fixed) == 0 ? new SourceMemberFieldSymbolFromDeclarator(this, variable, modifiers, modifierErrors, diagnostics) : new SourceFixedFieldSymbol(this, variable, modifiers, modifierErrors, diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(fieldSymbol); + builder.NonTypeMembers.Add(fieldSymbol); // All fields are included in the nullable context for constructors and initializers, even fields without // initializers, to ensure warnings are reported for uninitialized non-nullable fields in NullableWalker. builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: fieldSymbol.IsStatic, compilation, variable); @@ -5028,7 +5028,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, variable, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, variable, this, DeclarationModifiers.Private | (modifiers & DeclarationModifiers.Static), fieldSymbol); } @@ -5058,7 +5058,7 @@ private void AddNonTypeMembers( } var method = SourceOrdinaryMethodSymbol.CreateMethodSymbol(this, bodyBinder, methodSyntax, compilation.IsNullableAnalysisEnabledIn(methodSyntax), diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(method); + builder.NonTypeMembers.Add(method); } break; @@ -5073,7 +5073,7 @@ private void AddNonTypeMembers( bool isNullableEnabled = compilation.IsNullableAnalysisEnabledIn(constructorSyntax); var constructor = SourceConstructorSymbol.CreateConstructorSymbol(this, constructorSyntax, isNullableEnabled, diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(constructor); + builder.NonTypeMembers.Add(constructor); if (constructorSyntax.Initializer?.Kind() != SyntaxKind.ThisConstructorInitializer) { builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: constructor.IsStatic, isNullableEnabled); @@ -5095,7 +5095,7 @@ private void AddNonTypeMembers( // when it is loaded from metadata. Perhaps we should just treat it as an Ordinary // method in such cases? var destructor = new SourceDestructorSymbol(this, destructorSyntax, compilation.IsNullableAnalysisEnabledIn(destructorSyntax), diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(destructor); + builder.NonTypeMembers.Add(destructor); } break; @@ -5109,10 +5109,10 @@ private void AddNonTypeMembers( } var property = SourcePropertySymbol.Create(this, bodyBinder, propertySyntax, diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(property); + builder.NonTypeMembers.Add(property); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.SetMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, property.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, property.SetMethod); FieldSymbol? backingField = property.DeclaredBackingField; // TODO: can we leave this out of the member list? @@ -5121,7 +5121,7 @@ private void AddNonTypeMembers( // a similar manner and make the autoproperty fields private. if (backingField is { }) { - builder.NonTypeMembersWithPartialImplementations.Add(backingField); + builder.NonTypeMembers.Add(backingField); builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: backingField.IsStatic, compilation, propertySyntax); var initializer = propertySyntax.Initializer; @@ -5130,7 +5130,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the initializer - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, initializer, this, DeclarationModifiers.Private | (property.IsStatic ? DeclarationModifiers.Static : 0), @@ -5163,14 +5163,14 @@ private void AddNonTypeMembers( foreach (VariableDeclaratorSyntax declarator in eventFieldSyntax.Declaration.Variables) { SourceFieldLikeEventSymbol @event = new SourceFieldLikeEventSymbol(this, bodyBinder, eventFieldSyntax.Modifiers, declarator, diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(@event); + builder.NonTypeMembers.Add(@event); FieldSymbol? associatedField = @event.AssociatedField; if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, declarator, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, declarator, this, DeclarationModifiers.Private | (@event.IsStatic ? DeclarationModifiers.Static : 0), associatedField); } @@ -5198,8 +5198,8 @@ private void AddNonTypeMembers( Debug.Assert((object)@event.AddMethod != null); Debug.Assert((object)@event.RemoveMethod != null); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); } } break; @@ -5215,10 +5215,10 @@ private void AddNonTypeMembers( var @event = new SourceCustomEventSymbol(this, bodyBinder, eventSyntax, diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(@event); + builder.NonTypeMembers.Add(@event); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); Debug.Assert(@event.AssociatedField is null); } @@ -5235,9 +5235,9 @@ private void AddNonTypeMembers( var indexer = SourcePropertySymbol.Create(this, bodyBinder, indexerSyntax, diagnostics); builder.HaveIndexers = true; - builder.NonTypeMembersWithPartialImplementations.Add(indexer); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.SetMethod); + builder.NonTypeMembers.Add(indexer); + AddAccessorIfAvailable(builder.NonTypeMembers, indexer.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembers, indexer.SetMethod); } break; @@ -5252,7 +5252,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedConversionSymbol.CreateUserDefinedConversionSymbol( this, bodyBinder, conversionOperatorSyntax, compilation.IsNullableAnalysisEnabledIn(conversionOperatorSyntax), diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(method); + builder.NonTypeMembers.Add(method); } break; @@ -5267,7 +5267,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedOperatorSymbol.CreateUserDefinedOperatorSymbol( this, bodyBinder, operatorSyntax, compilation.IsNullableAnalysisEnabledIn(operatorSyntax), diagnostics); - builder.NonTypeMembersWithPartialImplementations.Add(method); + builder.NonTypeMembers.Add(method); } break; @@ -5294,7 +5294,7 @@ private void AddNonTypeMembers( foreach (var vdecl in decl.Declaration.Variables) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, vdecl, this, DeclarationModifiers.Private, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, vdecl, this, DeclarationModifiers.Private, containingFieldOpt: null); } break; @@ -5306,7 +5306,7 @@ private void AddNonTypeMembers( case SyntaxKind.ThrowStatement: case SyntaxKind.SwitchStatement: case SyntaxKind.LockStatement: - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, innerStatement, this, DeclarationModifiers.Private, From 978385d7669bce311f90d4638fa1e0150c804d25 Mon Sep 17 00:00:00 2001 From: AlekseyTs Date: Sat, 25 Jan 2025 18:27:58 -0800 Subject: [PATCH 6/6] Reapply "Rename" This reverts commit e3d22829d832ccf266ce089b6e48751add4a3981. --- .../Source/SourceMemberContainerSymbol.cs | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 18b343031917c..abb58e2d51de5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -2896,7 +2896,7 @@ private static void AddNestedTypesToDictionary( private sealed class DeclaredMembersAndInitializersBuilder { - public ArrayBuilder NonTypeMembers = ArrayBuilder.GetInstance(); + public ArrayBuilder NonTypeMembersWithPartialImplementations = ArrayBuilder.GetInstance(); public readonly ArrayBuilder> StaticInitializers = ArrayBuilder>.GetInstance(); public readonly ArrayBuilder> InstanceInitializers = ArrayBuilder>.GetInstance(); public bool HaveIndexers; @@ -2909,7 +2909,7 @@ private sealed class DeclaredMembersAndInitializersBuilder public DeclaredMembersAndInitializers ToReadOnlyAndFree(CSharpCompilation compilation) { return new DeclaredMembersAndInitializers( - NonTypeMembers.ToImmutableAndFree(), + NonTypeMembersWithPartialImplementations.ToImmutableAndFree(), MembersAndInitializersBuilder.ToReadOnlyAndFree(StaticInitializers), MembersAndInitializersBuilder.ToReadOnlyAndFree(InstanceInitializers), HaveIndexers, @@ -2939,7 +2939,7 @@ private ref bool GetIsNullableEnabledForConstructorsAndFields(bool useStatic) public void Free() { - NonTypeMembers.Free(); + NonTypeMembersWithPartialImplementations.Free(); foreach (var group in StaticInitializers) { @@ -3281,11 +3281,11 @@ public void Free() { case TypeKind.Struct: CheckForStructBadInitializers(builder, diagnostics); - CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: false, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: false, diagnostics: diagnostics); break; case TypeKind.Enum: - CheckForStructDefaultConstructors(builder.NonTypeMembers, isEnum: true, diagnostics: diagnostics); + CheckForStructDefaultConstructors(builder.NonTypeMembersWithPartialImplementations, isEnum: true, diagnostics: diagnostics); break; case TypeKind.Class: @@ -3596,7 +3596,7 @@ private void AddDeclaredNontypeMembers(DeclaredMembersAndInitializersBuilder bui break; case SyntaxKind.DelegateDeclaration: - SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembers, (DelegateDeclarationSyntax)syntax, diagnostics); + SourceDelegateMethodSymbol.AddDelegateMembers(this, builder.NonTypeMembersWithPartialImplementations, (DelegateDeclarationSyntax)syntax, diagnostics); break; case SyntaxKind.NamespaceDeclaration: @@ -4083,7 +4083,7 @@ private void AddEnumMembers(DeclaredMembersAndInitializersBuilder result, EnumDe symbol = SourceEnumConstantSymbol.CreateImplicitValuedConstant(this, member, otherSymbol, otherSymbolOffset, diagnostics); } - result.NonTypeMembers.Add(symbol); + result.NonTypeMembersWithPartialImplementations.Add(symbol); if (valueOpt != null || otherSymbol is null) { @@ -4230,7 +4230,7 @@ private void CheckForStructBadInitializers(DeclaredMembersAndInitializersBuilder } } - if (hasInitializers && !builder.NonTypeMembers.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) + if (hasInitializers && !builder.NonTypeMembersWithPartialImplementations.Any(member => member is MethodSymbol { MethodKind: MethodKind.Constructor })) { diagnostics.Add(ErrorCode.ERR_StructHasInitializersAndNoDeclaredConstructor, GetFirstLocation()); } @@ -5020,7 +5020,7 @@ private void AddNonTypeMembers( var fieldSymbol = (modifiers & DeclarationModifiers.Fixed) == 0 ? new SourceMemberFieldSymbolFromDeclarator(this, variable, modifiers, modifierErrors, diagnostics) : new SourceFixedFieldSymbol(this, variable, modifiers, modifierErrors, diagnostics); - builder.NonTypeMembers.Add(fieldSymbol); + builder.NonTypeMembersWithPartialImplementations.Add(fieldSymbol); // All fields are included in the nullable context for constructors and initializers, even fields without // initializers, to ensure warnings are reported for uninitialized non-nullable fields in NullableWalker. builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: fieldSymbol.IsStatic, compilation, variable); @@ -5028,7 +5028,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, variable, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, variable, this, DeclarationModifiers.Private | (modifiers & DeclarationModifiers.Static), fieldSymbol); } @@ -5058,7 +5058,7 @@ private void AddNonTypeMembers( } var method = SourceOrdinaryMethodSymbol.CreateMethodSymbol(this, bodyBinder, methodSyntax, compilation.IsNullableAnalysisEnabledIn(methodSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5073,7 +5073,7 @@ private void AddNonTypeMembers( bool isNullableEnabled = compilation.IsNullableAnalysisEnabledIn(constructorSyntax); var constructor = SourceConstructorSymbol.CreateConstructorSymbol(this, constructorSyntax, isNullableEnabled, diagnostics); - builder.NonTypeMembers.Add(constructor); + builder.NonTypeMembersWithPartialImplementations.Add(constructor); if (constructorSyntax.Initializer?.Kind() != SyntaxKind.ThisConstructorInitializer) { builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: constructor.IsStatic, isNullableEnabled); @@ -5095,7 +5095,7 @@ private void AddNonTypeMembers( // when it is loaded from metadata. Perhaps we should just treat it as an Ordinary // method in such cases? var destructor = new SourceDestructorSymbol(this, destructorSyntax, compilation.IsNullableAnalysisEnabledIn(destructorSyntax), diagnostics); - builder.NonTypeMembers.Add(destructor); + builder.NonTypeMembersWithPartialImplementations.Add(destructor); } break; @@ -5109,10 +5109,10 @@ private void AddNonTypeMembers( } var property = SourcePropertySymbol.Create(this, bodyBinder, propertySyntax, diagnostics); - builder.NonTypeMembers.Add(property); + builder.NonTypeMembersWithPartialImplementations.Add(property); - AddAccessorIfAvailable(builder.NonTypeMembers, property.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, property.SetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, property.SetMethod); FieldSymbol? backingField = property.DeclaredBackingField; // TODO: can we leave this out of the member list? @@ -5121,7 +5121,7 @@ private void AddNonTypeMembers( // a similar manner and make the autoproperty fields private. if (backingField is { }) { - builder.NonTypeMembers.Add(backingField); + builder.NonTypeMembersWithPartialImplementations.Add(backingField); builder.UpdateIsNullableEnabledForConstructorsAndFields(useStatic: backingField.IsStatic, compilation, propertySyntax); var initializer = propertySyntax.Initializer; @@ -5130,7 +5130,7 @@ private void AddNonTypeMembers( if (IsScriptClass) { // also gather expression-declared variables from the initializer - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, initializer, this, DeclarationModifiers.Private | (property.IsStatic ? DeclarationModifiers.Static : 0), @@ -5163,14 +5163,14 @@ private void AddNonTypeMembers( foreach (VariableDeclaratorSyntax declarator in eventFieldSyntax.Declaration.Variables) { SourceFieldLikeEventSymbol @event = new SourceFieldLikeEventSymbol(this, bodyBinder, eventFieldSyntax.Modifiers, declarator, diagnostics); - builder.NonTypeMembers.Add(@event); + builder.NonTypeMembersWithPartialImplementations.Add(@event); FieldSymbol? associatedField = @event.AssociatedField; if (IsScriptClass) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, declarator, this, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, declarator, this, DeclarationModifiers.Private | (@event.IsStatic ? DeclarationModifiers.Static : 0), associatedField); } @@ -5198,8 +5198,8 @@ private void AddNonTypeMembers( Debug.Assert((object)@event.AddMethod != null); Debug.Assert((object)@event.RemoveMethod != null); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); } } break; @@ -5215,10 +5215,10 @@ private void AddNonTypeMembers( var @event = new SourceCustomEventSymbol(this, bodyBinder, eventSyntax, diagnostics); - builder.NonTypeMembers.Add(@event); + builder.NonTypeMembersWithPartialImplementations.Add(@event); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.AddMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, @event.RemoveMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.AddMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, @event.RemoveMethod); Debug.Assert(@event.AssociatedField is null); } @@ -5235,9 +5235,9 @@ private void AddNonTypeMembers( var indexer = SourcePropertySymbol.Create(this, bodyBinder, indexerSyntax, diagnostics); builder.HaveIndexers = true; - builder.NonTypeMembers.Add(indexer); - AddAccessorIfAvailable(builder.NonTypeMembers, indexer.GetMethod); - AddAccessorIfAvailable(builder.NonTypeMembers, indexer.SetMethod); + builder.NonTypeMembersWithPartialImplementations.Add(indexer); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.GetMethod); + AddAccessorIfAvailable(builder.NonTypeMembersWithPartialImplementations, indexer.SetMethod); } break; @@ -5252,7 +5252,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedConversionSymbol.CreateUserDefinedConversionSymbol( this, bodyBinder, conversionOperatorSyntax, compilation.IsNullableAnalysisEnabledIn(conversionOperatorSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5267,7 +5267,7 @@ private void AddNonTypeMembers( var method = SourceUserDefinedOperatorSymbol.CreateUserDefinedOperatorSymbol( this, bodyBinder, operatorSyntax, compilation.IsNullableAnalysisEnabledIn(operatorSyntax), diagnostics); - builder.NonTypeMembers.Add(method); + builder.NonTypeMembersWithPartialImplementations.Add(method); } break; @@ -5294,7 +5294,7 @@ private void AddNonTypeMembers( foreach (var vdecl in decl.Declaration.Variables) { // also gather expression-declared variables from the bracketed argument lists and the initializers - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, vdecl, this, DeclarationModifiers.Private, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, vdecl, this, DeclarationModifiers.Private, containingFieldOpt: null); } break; @@ -5306,7 +5306,7 @@ private void AddNonTypeMembers( case SyntaxKind.ThrowStatement: case SyntaxKind.SwitchStatement: case SyntaxKind.LockStatement: - ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembers, + ExpressionFieldFinder.FindExpressionVariables(builder.NonTypeMembersWithPartialImplementations, innerStatement, this, DeclarationModifiers.Private,