-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Partial events and constructors: merge and check symbols #76970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial events and constructors: merge and check symbols #76970
Conversation
src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceConstructorSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbol.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceFieldLikeEventSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventDefinitionAccessorSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventDefinitionAccessorSymbol.cs
Outdated
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceEventDefinitionAccessorSymbol.cs
Outdated
Show resolved
Hide resolved
| Debug.Assert((object)AdaptedMethodSymbol.PartialDefinitionPart == null); // must be definition | ||
| if (AdaptedMethodSymbol.PartialDefinitionPart is { } definition) | ||
| { | ||
| return definition.GetCciAdapter().ResolvedMethodImpl(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change was needed to avoid crash in the sequence point test (added in the same commit). Similar test would also crash for partial methods/properties. Basically the VerifyMethodBody test helper calls GetResolvedMethod on the implementation Cci symbol - that probably doesn't happen normally during emit, that's why the assert was fine for normal scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any risk that this is adding a new capability to users of the public API, that they may come to depend on, and we didn't intend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are Cci adapters public API? Anyway I think this was simply wrong before. And users of public APIs would probably not hit the assert (because they use Release bits), so they would just get the wrong result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change doesn't look right. I think the API is not supposed to return a different instance, it should either return an original instance, or null. Basically, for a pair of partial declarations, we should never "create" two different adapters, translation layer should make sure of that. Symbols should never be casted to CCI interfaces, they should be translated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly, PEModuleBuilder performs the translation. There are APIs called "Translate..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, thanks, I think I can skip the failing test for now and look at this separately. Or better yet, I can simply fix this inside the test utility.
|
@RikkiGibson for another look, thanks |
|
@RikkiGibson for a second review, thanks |
RikkiGibson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had some minor comments but otherwise LGTM.
| Debug.Assert((object)AdaptedMethodSymbol.PartialDefinitionPart == null); // must be definition | ||
| if (AdaptedMethodSymbol.PartialDefinitionPart is { } definition) | ||
| { | ||
| return definition.GetCciAdapter().ResolvedMethodImpl(context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any risk that this is adding a new capability to users of the public API, that they may come to depend on, and we didn't intend?
| isIterator: false, | ||
| isNullableAnalysisEnabled: ev.DeclaringCompilation.IsNullableAnalysisEnabledIn(ev.CSharpSyntaxNode), | ||
| isExpressionBodied: false) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider asserting ev.IsPartialDefinition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, turns out that wasn't true for extern events (because the extern partial part is the implementation part), so I fixed that as well.
|
|
||
| static void mergeAccessors(ArrayBuilder<Symbol> nonTypeMembers, SourceEventAccessorSymbol? currentAccessor, SourceEventAccessorSymbol? prevAccessor) | ||
| { | ||
| if (currentAccessor?.IsPartialImplementation == true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is an intentional simplification compared to how properties handle it? Since there isn't a need to detect a condition where one of the accessors is missing on the definition part. For a property, I think we take care to keep the implementation part accessor in the member list in that case.
There is no way to elide an accessor on the definition part here, though, so this implementation is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's correct.
| class [mscorlib]System.Action 'value' | ||
| ) cil managed | ||
| { | ||
| } // end of method C::add_E |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused by this. Is this saying that these methods have implementations in this assembly? I thought extern means they would not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think they have only signatures in the metadata, not bodies. The IL decompiler shows it like this though.
| } | ||
| } | ||
| """; | ||
| // PROTOTYPE: Mismatch between accessibility modifiers of parts should be reported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is still tracked to be completed in a future PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just not in this test anymore, I changed it so there is no mismatch so it actually tests what it's supposed to test.
|
@RikkiGibson can you take another look? thanks |
Test plan: #76859