-
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
Deconstruction-declaration parsing for local declaration, for and foreach #12104
Conversation
foreach statements
// foreach ( <type> <identifier> in <expr> ) <embedded-statement> | ||
// or | ||
// foreach ( <deconstruction-variables> in <expr> ) <embedded-statement> |
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.
The name implies to me that it can only be variables. I assume we can have declarations here as well.
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.
Fixed the comment.
Hold off any reviews. From discussion with Cyrus and Aleksey, I'm going to remove the terminals I introduced (to represent "type id" or "id") and use |
@dotnet/roslyn-compiler This is ready to review again. Two examples:
To recap,
|
|
||
this.Reset(ref resetPoint); | ||
if ((object)decl == null) |
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.
Minor point: CSharpSyntaxNode
does not define ==
so the cast to object
is unnecessary.
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.
Fixed here and other similar instances below. Thanks
Just pushed a PR addressing Chuck and Cyrus's feedback. |
|
||
if (this.CurrentToken.Kind != SyntaxKind.CloseParenToken) | ||
{ | ||
VariableDeclarationSyntax variable; |
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.
variable
declaration can be moved inside while
.
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
return null; | ||
} | ||
|
||
return CheckFeatureAvailability(result, MessageID.IDS_FeatureTuples); |
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.
Please add tests for this check, positive and negative. #Resolved
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.
Added CSharp6 test. Positive tests will be easier once I have some binding, so they will be added in subsequent PRs.
This change to public API is not ready yet. I have more changes coming. |
Ok, the latest commit I pushed provides a more reasonable public API. If anything, some APIs could be added for convenience. |
; | ||
|
||
for_statement | ||
: 'for' '(' for_initializer? ';' for_condition? ';' for_iterator? ')' embedded_statement | ||
; |
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.
Has for_statement
changed or is the same as without deconstruction variables?
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.
In the grammar, I kept for_statement
as before. The difference appears below, in for_initializer
.
What kind of parse errors do we report for contexts where deconstruct is not allowed? For instance |
LGTM |
@@ -1809,11 +1809,29 @@ | |||
<Kind Name="SemicolonToken"/> | |||
</Field> | |||
</Node> | |||
<Node Name="VariableDeclarationSyntax" Base="CSharpSyntaxNode"> | |||
|
|||
<Node Name="VariableDeconstructionDeclaratorSyntax" Base="CSharpSyntaxNode" AvoidAutoCreation="true" InternalConstructor="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.
Should this say InternalFactory rather than constructor? #Resolved
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.
Sure. Renamed.
@cston, I will take a note on your question (should we report errors for un-supported contexts?). |
@@ -117,6 +119,20 @@ Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.Update(Microsoft.CodeAnalys | |||
Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax | |||
Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithElements(Microsoft.CodeAnalysis.SeparatedSyntaxList<Microsoft.CodeAnalysis.CSharp.Syntax.TupleElementSyntax> elements) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax | |||
Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax | |||
Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax.Deconstruction.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeconstructionDeclaratorSyntax | |||
Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax.WithDeconstruction(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeconstructionDeclaratorSyntax deconstruction) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax |
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 would expect this method to remove regular variables and even type when it has an incompatible value. Does it?
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.
An existing VariableDeclarationSyntax.WithVariables should probably be also adjusted accordingly.
In reply to: 68451298 [](ancestors = 68451298,68451172)
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 added two work items to track this:
- Add validation to factory methods (only allow creating valid combinations with reasonable-looking children)
- Add validation logic or erasure to WithXYZ methods
Thanks for raising the questions.
LGTM |
Thanks both for the review and feedback. I'll go ahead with merge. |
Adds parsing for three deconstruction-declaration contexts. Other contexts (such as
let
orfrom
will be added later).@dotnet/roslyn-compiler for review. Thanks
Note 1: because my VS is busted, I expect some public API errors. I will fix that before checking in.
Note 2: this change includes a copy of Aleksey's recent change in outvar branch to support Internal="true" in Syntax.xml, which will help maintain a backwards compatible public API.
Issue #11299