From d78fda7275a9e84bd0b599270efa9700e9f4bf16 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Thu, 9 Mar 2017 21:29:17 -0800 Subject: [PATCH] Refine syntax error recovery for partial code to not interfere with non-error code. Related to #15885 Fixes #17683 --- .../CSharp/Portable/Parser/LanguageParser.cs | 2 +- .../Syntax/Parsing/ExpressionParsingTests.cs | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 22c6b53182f7b..86d0f4447e898 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -9386,7 +9386,7 @@ private ExpressionSyntax ParsePostFixExpression(ExpressionSyntax expr) // there is a new declaration on the next line. if (this.CurrentToken.TrailingTrivia.Any((int)SyntaxKind.EndOfLineTrivia) && this.PeekToken(1).Kind == SyntaxKind.IdentifierToken && - this.PeekToken(2).Kind == SyntaxKind.IdentifierToken) + this.PeekToken(2).ContextualKind == SyntaxKind.IdentifierToken) { expr = _syntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, expr, this.EatToken(), diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs index 184cbd0c2a940..15abb2c6810b9 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs @@ -3533,5 +3533,127 @@ void M() EOF(); } + [Fact, WorkItem(17683, "https://github.com/dotnet/roslyn/issues/17683")] + public void Bug17683a() + { + var source = +@"from t in e +where +t == Int32. +MinValue +select t"; + UsingExpression(source); + N(SyntaxKind.QueryExpression); + { + N(SyntaxKind.FromClause); + { + N(SyntaxKind.FromKeyword); + N(SyntaxKind.IdentifierToken, "t"); + N(SyntaxKind.InKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + } + N(SyntaxKind.QueryBody); + { + N(SyntaxKind.WhereClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.EqualsExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "t"); + } + N(SyntaxKind.EqualsEqualsToken); + N(SyntaxKind.SimpleMemberAccessExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "MinValue"); + } + } + } + } + N(SyntaxKind.SelectClause); + { + N(SyntaxKind.SelectKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "t"); + } + } + } + } + EOF(); + } + + [Fact] + public void Bug17683b() + { + var source = +@"switch (e) +{ + case Int32. + MaxValue when true: + break; +}"; + UsingStatement(source); + N(SyntaxKind.SwitchStatement); + { + N(SyntaxKind.SwitchKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "e"); + } + N(SyntaxKind.CloseParenToken); + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.SwitchSection); + { + N(SyntaxKind.CasePatternSwitchLabel); + { + N(SyntaxKind.CaseKeyword); + N(SyntaxKind.ConstantPattern); + { + N(SyntaxKind.SimpleMemberAccessExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.DotToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "MaxValue"); + } + } + } + N(SyntaxKind.WhenClause); + { + N(SyntaxKind.WhenKeyword); + N(SyntaxKind.TrueLiteralExpression); + { + N(SyntaxKind.TrueKeyword); + } + } + N(SyntaxKind.ColonToken); + } + N(SyntaxKind.BreakStatement); + { + N(SyntaxKind.BreakKeyword); + N(SyntaxKind.SemicolonToken); + } + } + N(SyntaxKind.CloseBraceToken); + } + EOF(); + } } } \ No newline at end of file