Skip to content

Fix a few param-nullchecking parsing bugs#58644

Merged
RikkiGibson merged 18 commits intodotnet:release/dev17.1from
RikkiGibson:pnc-fix-parsing
Jan 7, 2022
Merged

Fix a few param-nullchecking parsing bugs#58644
RikkiGibson merged 18 commits intodotnet:release/dev17.1from
RikkiGibson:pnc-fix-parsing

Conversation

@RikkiGibson
Copy link
Copy Markdown
Member

@RikkiGibson RikkiGibson commented Jan 5, 2022

Closes #58585

Thanks to Cyrus for the greater part of the work here.

Relates to test plan #36024

@ghost ghost added the Area-Compilers label Jan 5, 2022
&& this.PeekToken(3).Kind == SyntaxKind.ExclamationToken
&& after.GetTrailingTriviaWidth() == 0
&& this.PeekToken(3).GetLeadingTriviaWidth() == 0
&& token3.Kind == SyntaxKind.ExclamationToken
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentionally removed this restriction.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we are accepting this during scanning so we can give a better parse with errors, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct! it also means there's uniform 'token handling' that goes in before calling the helper. none of these scanners (or hte helper) care about having this requirement. it means they're all resilient to accidental spaces happening as you edit.

&& this.PeekToken(1).Kind == SyntaxKind.ExclamationToken
&& this.CurrentToken.GetTrailingTriviaWidth() == 0
&& this.PeekToken(1).GetLeadingTriviaWidth() == 0)
&& this.PeekToken(1).Kind == SyntaxKind.ExclamationToken)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentionally removed this restriction.

&& this.PeekToken(3).Kind == SyntaxKind.ExclamationToken
&& after.GetTrailingTriviaWidth() == 0
&& this.PeekToken(3).GetLeadingTriviaWidth() == 0
&& token3.Kind == SyntaxKind.ExclamationToken
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we are accepting this during scanning so we can give a better parse with errors, right?

&& this.PeekToken(3).Kind == SyntaxKind.GreaterThanToken)
if (token1.Kind == SyntaxKind.ExclamationToken
&& token2.Kind == SyntaxKind.ExclamationEqualsToken
&& token3.Kind == SyntaxKind.GreaterThanToken)
Copy link
Copy Markdown
Member Author

@RikkiGibson RikkiGibson Jan 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary to change it but I wonder if this if and the preceding ifs would combine nicely as a pattern switch statement, or even something like

if ((token1.Kind, token2.Kind, token3.Kind) is ('!', '!', '=>') or ('!=', '>', _) or ('!', '!=', '>')) return true;

except with the proper use of SyntaxKind enum and proper indenting of course.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup. i def like that!

UsingDeclaration("Func<string[], string> func0 = (x[]) => x;", options: TestOptions.RegularPreview,
// (1,36): error CS1001: Identifier expected
// Func<string[], string> func0 = (x[]) => x;
Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(1, 36)); N(SyntaxKind.FieldDeclaration);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind this parse, but I was confused that it expected an identifier instead of ).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. let me look into that!

UsingDeclaration("Func<string, string> func0 = (y, x = null) => x;", options: TestOptions.RegularPreview,
// (1,44): error CS1003: Syntax error, ',' expected
// Func<string, string> func0 = (y, x = null) => x;
Diagnostic(ErrorCode.ERR_SyntaxError, "=>").WithArguments(",", "=>").WithLocation(1, 44)); N(SyntaxKind.FieldDeclaration);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does make me wonder if there is more room to unify on parameter lists in parenthesized lambdas and non-lambdas, and if we could simplify the parser and move some errors like these to binding in the process.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is definitely possible. the IsPossibleLambda will have to do much more speculative parsing to handle the = null places whatnot. I put these tests in though so we could see the improvement if we do that.

i'm open to doing more in this PR if you've like!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider it a "design debt" issue to address in the future.

@RikkiGibson RikkiGibson marked this pull request as ready for review January 6, 2022 18:40
@RikkiGibson RikkiGibson requested a review from a team as a code owner January 6, 2022 18:40
@RikkiGibson RikkiGibson changed the base branch from main to release/dev17.1 January 6, 2022 18:56
@RikkiGibson
Copy link
Copy Markdown
Member Author

RikkiGibson commented Jan 6, 2022

The test failure in Unix is due to a whitespace/line ending difference. Haven't quite figured out how to hammer it down.

edit: resolved by eliminating the problematic test scenario. I don't think the scenario is valuable enough to warrant further effort working around the cross-plat/test framework issue.

Co-authored-by: Charles Stoner <10732005+cston@users.noreply.github.com>
@cston

This comment has been minimized.

RikkiGibson and others added 2 commits January 6, 2022 14:03
Co-authored-by: Charles Stoner <10732005+cston@users.noreply.github.com>
@@ -129,59 +129,49 @@ public void NullCheckedBadSyntax()
#pragma warning disable CS8893
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning disable CS8893

Was this #pragma disabling the warning previously? Does it now? (Was there a reason to change the parameter default value from null in each of the methods?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sigh yes, some renumbering must have broken it. I feel it's simpler to use a literal string here, so if you don't object I'd like to keep it as it is in this PR. But I will delete the pragma.

Copy link
Copy Markdown
Member

@chsienki chsienki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@RikkiGibson RikkiGibson enabled auto-merge (squash) January 7, 2022 00:01
@RikkiGibson RikkiGibson merged commit 0e5c679 into dotnet:release/dev17.1 Jan 7, 2022
@RikkiGibson RikkiGibson deleted the pnc-fix-parsing branch January 7, 2022 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid null-checked parameter syntax doesn't cause errors.

5 participants