Skip to content
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

Improve lexer error recovery with interpolated strings. #54875

Merged
merged 49 commits into from
Jul 25, 2021

Conversation

CyrusNajmabadi
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi commented Jul 16, 2021

The current lexer strategy with interpolations is to bail early when it encounters something like a spurious newline in a non-verbatim interpolation. This means that simple user cases like:

var v = $"Hello { @""
                   World
                   "" } !";

Go entirely off the rails. since the lexer stops processing that at: var v = $"Hello { @"" leaving the rest to be restarted. This of course throws everything off as the contents of the string become code and then later quotes look to start new strings (like "; ...). Furthermore the close curlies found later then just destroy the rest of hte parsing stack, leading to everything being awful.

This PR changes our strategy here to actually recognize when we are running into errant newlines (either in the interpolation code, or comments, or multiline verbatim literals), and while it treats that as an error, it still allows normal lexing of these constructs to proceed, producing a good tree with a good error message.

This cleanup helps the Raw-String-Literals work (esp. around how it handles interpolations). However, it can be done independently to keep things tidier and simpler.

TextWindow.AdvanceChar(2);

ErrorCode? error = null;
while (true)
{
Copy link
Member Author

@CyrusNajmabadi CyrusNajmabadi Jul 16, 2021

Choose a reason for hiding this comment

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

no need for this 'if' check, the callers ensure it. so this became a Debug assert, with no else. #Resolved

@jcouv
Copy link
Member

jcouv commented Jul 16, 2021

Is this related to the raw string literal work? If so, should this go into the feature branch so that you don't have to wait for another merge from main?


In reply to: 881702367


In reply to: 881702367

@CyrusNajmabadi
Copy link
Member Author

Is this related to the raw string literal work?

Tangentially. THis is pure cleanup and improvement though that can go in outside of the raw string literal work. that's why i decoupled it and brought it into main.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner July 16, 2021 22:45
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddParenthesesAroundConditionalExpressionInInterpolatedString)]
public async Task TestAddParenthesesClosingBracketInFalseCondition()
{
await TestInMethodAsync(
@"var s = $""{ true ? new int[0] [|:|] new int[] {} }"";",
@"var s = $""{ (true ? new int[0] : new int[] {} )}"";");
@"var s = $""{ (true ? new int[0] : new int[] {}) }"";");
Copy link
Member Author

Choose a reason for hiding this comment

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

these results are actually preferred as we do not have the bogus space after the WhenFalse part.

@@ -88,71 +88,71 @@ public async Task TestAddParenthesesWithTrivia()
{
await TestInMethodAsync(
@"var s = $""{ /* Leading1 */ true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */[|:|] /* FalsePart1 */ 2 /* FalsePart2 */ }"";",
@"var s = $""{ /* Leading1 */ (true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */: /* FalsePart1 */ 2 /* FalsePart2 */ )}"";");
@"var s = $""{ /* Leading1 */ (true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */: /* FalsePart1 */ 2) /* FalsePart2 */ }"";");
Copy link
Member Author

Choose a reason for hiding this comment

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

preferred as this is symettrical with what we do with Leading1. both the open and close parens tightly bind the expression code itself, not the surrounding trivia.

@CyrusNajmabadi
Copy link
Member Author

tagging @jcouv @333fred or anyone on the compiler who would like to take a look :)

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

Done with review pass (iteration 38)

@jcouv
Copy link
Member

jcouv commented Jul 22, 2021

Looks like a couple of tests were affected (break in CI)

@CyrusNajmabadi
Copy link
Member Author

Looks like a couple of tests were affected (break in CI)

Yeah, looks like the approach of picking the earliest error was necessary. I've moved to your model, but have preserved that logic.

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

LGTM (commit 42)

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

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

LGTM (iteration 43). Don't forget to squash please. Thanks

@CyrusNajmabadi CyrusNajmabadi enabled auto-merge (squash) July 22, 2021 17:35
@CyrusNajmabadi
Copy link
Member Author

Yup. I'm set to squash things. Thanks!

@jcouv
Copy link
Member

jcouv commented Jul 23, 2021

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@333fred
Copy link
Member

333fred commented Jul 23, 2021

@CyrusNajmabadi looks like there's a legitimate test failure.

@CyrusNajmabadi CyrusNajmabadi merged commit 87b3b66 into dotnet:main Jul 25, 2021
@ghost ghost added this to the Next milestone Jul 25, 2021
@allisonchou allisonchou modified the milestones: Next, 17.0.P3 Jul 27, 2021
@CyrusNajmabadi CyrusNajmabadi deleted the lexingRecovery branch July 31, 2021 01:49
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.

None yet

5 participants