-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Collection expression argument parsing ([with(x, y, z), a, b, c]
).
#76003
Collection expression argument parsing ([with(x, y, z), a, b, c]
).
#76003
Conversation
This PR modifies public API files. Please follow the instructions at https://github.com/dotnet/roslyn/blob/main/docs/contributing/API%20Review%20Process.md for ensuring all public APIs are reviewed before merging. |
var element = syntax.Elements[i]; | ||
if (element is WithElementSyntax withElement) | ||
{ | ||
Error(diagnostics, ErrorCode.ERR_WithElementMustBeFirst, withElement.WithKeyword.GetLocation()); |
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.
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.
likely not. t his was just the parsing PR. binding/testing was intended for you to do :)
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 we're adding an error code and binding logic, we should test it. Either way seems fine for this PR (remove logic or test)
{ | ||
if (element is KeyValuePairElementSyntax keyValuePairElement) | ||
{ | ||
MessageID.IDS_FeatureDictionaryExpressions.CheckFeatureAvailability(diagnostics, syntax, keyValuePairElement.ColonToken.GetLocation()); |
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.
} | ||
else if (element is WithElementSyntax withElement) | ||
{ | ||
MessageID.IDS_FeatureCollectionExpressionConstructionArguments.CheckFeatureAvailability(diagnostics, syntax, withElement.WithKeyword.GetLocation()); |
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.
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.
likely not. t his was just the parsing PR. binding/testing was intended for you to do :)
|
||
// PROTOTYPE: Error for now. Flesh this out when we do the binding for `with(...)` arguments. | ||
Error(diagnostics, ErrorCode.ERR_SyntaxError, withElement.WithKeyword, ","); | ||
return new BoundBadExpression(syntax, LookupResultKind.Empty, symbols: [], childBoundNodes: [], CreateErrorType()); |
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.
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 was just to unblock the PR. i would expect us to want us to be very resilient in practice. but i did no binding work.
@@ -295,6 +295,7 @@ internal enum MessageID | |||
|
|||
IDS_FeatureFirstClassSpan = MessageBase + 12849, | |||
IDS_FeatureDictionaryExpressions = MessageBase + 12850, | |||
IDS_FeatureCollectionExpressionConstructionArguments = MessageBase + 12851, |
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 shortening, perhaps to IDS_FeatureCollectionExpressionArguments
. #Closed
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.
done.
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.
LGTM.
Please squash commits when merging, thanks.
return (WithElementSyntax)Syntax.InternalSyntax.SyntaxFactory.WithElement((Syntax.InternalSyntax.SyntaxToken)withKeyword.Node!, (Syntax.InternalSyntax.ArgumentListSyntax)argumentList.Green).CreateRed(); | ||
} | ||
|
||
#pragma warning disable RS0027 |
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.
note: this required changing the generator. but we've done that in the past for this exact issue. fbofw our generator generates a pattern which our RS rules don't particularly like (though we haven't had an actual problem with the syntax apis here, so it just is a conflict in philosophy).
if (element is WithElementSyntax withElement) | ||
{ | ||
Error(diagnostics, ErrorCode.ERR_WithElementMustBeFirst, withElement.WithKeyword.GetLocation()); | ||
break; |
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.
Why are we breaking out of the loop? #Closed
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.
because we reported the error on the first vioaltor. I didn't see any value in continuing to report on further violations :)
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.
taht said, binding behavior is entirely in chuck's court. if he wants to change this, i have no issue with that.
...torFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
Show resolved
Hide resolved
@@ -1688,8 +1688,8 @@ private void WriteRedMinimalFactory(Node nd, bool withStringNames = false) | |||
|
|||
var hasOptional = minimalFactoryfields.Any(f => !IsRequiredFactoryField(nd, f)); | |||
var hasAttributeOrModifiersList = nd.Fields.Any(f => IsAttributeOrModifiersList(f)); | |||
|
|||
if (hasOptional && hasAttributeOrModifiersList) | |||
var writePragma = hasOptional && (hasAttributeOrModifiersList || nd.Name == "WithElementSyntax"); |
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'm lacking context. What is RS0027 and why does WithElementSyntax
need special treatment here? #Closed
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 marked the place in teh PR where this has impact. RS2007 says that you should not have APIs that have optional members, if there is an api that has more non optional arguments. Thi sis a suspect, and unmainted roslyn-specific rule that we violate all the time. Basically, it's fine that one can do SyntaxFactory.WithElement()
or SyntaxFactory.WithElement(someWithKeyword, someArgList)
.
this just suppresses that warning in the generated code (which we do with many other nodes).
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
Just to confirm these are the two APIs that would cause that analyzer diagnostic?
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WithElement(Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax? argumentList = null) -> Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax!
static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WithElement(Microsoft.CodeAnalysis.SyntaxToken withKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax! argumentList) -> Microsoft.CodeAnalysis.CSharp.Syntax.WithElementSyntax!
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.
correct.
[Fact] | ||
public void WithElement2() | ||
{ | ||
UsingExpression("[with()]"); |
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 looks like a breaking change. Let's document it.
Should it be made LangVer-dependent? #Closed
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.
We can doc, but def want to run by ldm first. Our investigations here indicate no usage of this in the wild. So we're going to see if we can get buyoff on this just being a unilateral break .
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 is part of hte final syntax/sign-off discussion there.
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.
Should it be made LangVer-dependent?
This is currently an open question.
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.
Since the PR implements a break, let's add a PROTOTYPE marker (to test with LangVer and document break).
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.
open LDM question.
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.
Since the PR implements a break, let's add a PROTOTYPE marker (to test with LangVer and document break).
Done.
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.
UsingExpression("[with()]"); | |
// PROTOTYPE test with LangVer and document break | |
UsingExpression("[with()]"); |
My reasoning for pushing on this: If LDM were to approve the break as it is implemented by this PR, so nobody revisits this code, who is going to remember that we didn't document it? Usually, PRs that implement breaks also document them.
Thanks. I see this was addressed elsewhere
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.
LGTM Thanks!
f806fd4
into
dotnet:features/dictionary-expressions
An exploration around adding a
with(...arguments...)
element to collection expressions, to allow arguments to be passed to the final created collection. For example, for:Dictionary<string, int> nameToAge = [with(StringComparer.CaseInsensitive), "mads": 21, .. existingDic]
.Relates to test plan #76310