Make SourceClonedParameterSymbol abstract#54355
Make SourceClonedParameterSymbol abstract#54355jcouv merged 13 commits intodotnet:features/caller-argument-expressionfrom
Conversation
5e45818 to
55b6ebe
Compare
|
@AlekseyTs This is ready for review. Thanks! |
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Show resolved
Hide resolved
|
Done with review pass (commit 1) |
|
|
||
| internal override bool IsCallerMemberName => _originalParam.IsCallerMemberName; | ||
|
|
||
| internal override int CallerArgumentExpressionParameterIndex => throw ExceptionUtilities.Unreachable; |
There was a problem hiding this comment.
@AlekseyTs The created parameter may not be optional as you stated in the other PR. However, I think this is still unreachable. We attempt to bind default arguments only if overload resolution succeeds.
If overload resolution succeeds, then an explicit value was passed to the parameter, meaning we are not going to access this property (I'm open to adding any test cases you'd like if the existing tests are not enough). #Resolved
There was a problem hiding this comment.
If overload resolution succeeds, then an explicit value was passed to the parameter, meaning we are not going to access this property.
That maybe true for EndEnvoke (I assume because parameters are ref/out/in), but why this is true for BeginInvoke is not obvious to me.
I'm open to adding any test cases you'd like if the existing tests are not enough
I think we should have targeted test for Begin/EndInvoke invocations for scenarios when cloned parameters are optional and have the attribute on them.
There was a problem hiding this comment.
Both BeginInvoke and EndInvoke has extra parameter(s) at the end (AsyncCallBack and object for BeginInvoke, and IAsyncResult for EndInvoke). If overload resolution succeeds, then these parameters must have been supplied, meaning all the previous parameters has explicitly been passed.
I'll add some tests.
There was a problem hiding this comment.
Both
BeginInvokeandEndInvokehas extra parameter(s) at the end (AsyncCallBackandobjectforBeginInvoke, andIAsyncResultforEndInvoke). If overload resolution succeeds, then these parameters must have been supplied, meaning all the previous parameters has explicitly been passed.
I see now why this is wrong.
|
@AlekseyTs This is ready for another look. Thanks! |
| public class AttributeTests_CallerInfoAttributes : WellKnownAttributesTestBase | ||
| { | ||
| [ConditionalFact(typeof(CoreClrOnly))] | ||
| public void TestBeginInvoke() |
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Outdated
Show resolved
Hide resolved
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Outdated
Show resolved
Hide resolved
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Outdated
Show resolved
Hide resolved
|
Done with review pass (commit 2) |
…ssion' into caller-arg-cloned-param
| class Program | ||
| { | ||
| const string s1 = nameof(s1); | ||
| delegate void D(ref string s1, [CallerArgumentExpression(s1)] [Optional] [DefaultParameterValue(""default"")] string s2); |
There was a problem hiding this comment.
[CallerArgumentExpression(s1)] [Optional] [DefaultParameterValue(""default"")] string s2
The interesting scenario is when this parameter is getting cloned and the one that it references isn't and probably follows it. Is this the case in this unit-test. We want to test scenario where simply reusing the index from the original parameter will be observably wrong. #Closed
There was a problem hiding this comment.
The interesting scenario is when this parameter is getting cloned and the one that it references isn't
For the parameter to get cloned, it must be ref if I understand correctly. ref parameters seem to have a false IsOptional. Hence, the test won't hit calling CallerArgumentExpressionIndex. This is regardless we're in error case or not.
I think the test you're asking for should hit CallerArgumentExpressionIndex. I'm unable to find a test case that fulfills all the following:
- The
CallerArgumentExpressionparameter is cloned. - The parameter it refers to isn't cloned.
CallerArgumentExpressionIndexgets hit.
I added a test that fulfills 1 and 2.
There was a problem hiding this comment.
For the parameter to get cloned, it must be ref if I understand correctly. ref parameters seem to have a false IsOptional. Hence, the test won't hit calling CallerArgumentExpressionIndex. This is regardless we're in error case or not.
We still can have a test attempting to do that. Trying all possible ways marking the parameter optional, attempting to ommit it at the call-site. It is fine if we will be unable to hit the API. We still need tests that attempt to do that.
There was a problem hiding this comment.
@AlekseyTs I added a test in 25dd0ff, and added two more now in 8ee88e0. Let me know if there are any other scenarios :)
|
Done with review pass (commit 6) |
| class Program | ||
| { | ||
| const string s2 = nameof(s2); | ||
| delegate void D([CallerArgumentExpression(s2)] [Optional] [DefaultParameterValue(""default"")] ref string s1, string s2); |
| { | ||
| D d = M; | ||
| string s = string.Empty; | ||
| d.EndInvoke(ref s, null); |
| { | ||
| D d = M; | ||
| string s = string.Empty; | ||
| d.EndInvoke(ref s, null); |
|
Done with review pass (commit 10) |
|
|
Pinging @AlekseyTs and @333fred for review. Thanks! |
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Show resolved
Hide resolved
| "; | ||
|
|
||
| var compilation = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularPreview); | ||
| // Begin/EndInvoke are not currently supported. |
There was a problem hiding this comment.
@333fred No, I meant "supported by the compiler". ie, the compiler doesn't do anything for caller argument expressions for cloned begin/end invoke parameters.
|
Done review pass (commit 11). Only a few small comments for clarifications. |
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Outdated
Show resolved
Hide resolved
…nedParameterSymbolForBeginAndEndInvoke.cs
...rs/CSharp/Portable/Symbols/Source/SourceDelegateClonedParameterSymbolForBeginAndEndInvoke.cs
Outdated
Show resolved
Hide resolved
…nedParameterSymbolForBeginAndEndInvoke.cs
333fred
left a comment
There was a problem hiding this comment.
LGTM (commit 13). @dotnet/roslyn-compiler for a second review.
|
@jcouv Can you review please? Thanks! |
|
Ping @jcouv |
| { | ||
| } | ||
|
|
||
| internal override bool IsCallerFilePath => _originalParam.IsCallerFilePath; |
There was a problem hiding this comment.
I didn't understand why properties that are implemented the same way in SourceDelegateClonedParameterSymbolForBeginAndEndInvoke and SourcePropertyClonedParameterSymbolForAccessors were moved out of the base type.
There was a problem hiding this comment.
@jcouv This was requested by @AlekseyTs. The reasoning is to force new types to implement it. i.e, avoid future mistakes if a new type should implement it another way.
| IL_001e: ret | ||
| } | ||
| "); | ||
| } |
There was a problem hiding this comment.
It looks like the added tests cover delegate scenarios. Do we already have scenarios for properties/indexers, since that's another scenario that uses SourceClonedParameterSymbol?
There was a problem hiding this comment.
jcouv
left a comment
There was a problem hiding this comment.
Done with review pass (iteration 13). Just a couple of questions
|
Also it occurred to me that we'll want to think of possible interactions between CallerArgumentExpression and interpolated string handlers. |
Clarified from chat with Fred. Here's possible scenario (may just fall out): |
Builds on #54132 (I'll rebase once the other PR goes in).I think there is no need to wait on the other PR. Going to rebase on the current feature branch.@AlekseyTs Let me know if you want the other PR to contain everything.
Proposal: dotnet/csharplang#287
Test plan: #52745