提交 38281970 编写于 作者: N Neal Gafter

Merge pull request #6731 from gafter/fix6726

Enforce the precedence of a query expression
......@@ -198,7 +198,7 @@ protected override bool NeedsProxy(Symbol localOrParameter)
// No closures or lambda methods are generated.
// E.g.
// int y = 0;
// var b = false && from z in new X(y) select f(z + y)
// var b = false && (from z in new X(y) select f(z + y))
return loweredBody;
}
......
......@@ -6500,7 +6500,7 @@ private StatementSyntax ParseStatementNoDeclaration(bool allowAnyExpression)
}
else if (this.IsQueryExpression(mayBeVariableDeclaration: true, mayBeMemberDeclaration: allowAnyExpression))
{
return this.ParseExpressionStatement(this.ParseQueryExpression());
return this.ParseExpressionStatement(this.ParseQueryExpression(0));
}
else
{
......@@ -8330,7 +8330,7 @@ private ExpressionSyntax ParseSubExpressionCore(uint precedence)
}
else if (this.IsQueryExpression(mayBeVariableDeclaration: false, mayBeMemberDeclaration: false))
{
leftOperand = this.ParseQueryExpression();
leftOperand = this.ParseQueryExpression(precedence);
}
else if (this.CurrentToken.ContextualKind == SyntaxKind.FromKeyword && IsInQuery)
{
......@@ -8448,10 +8448,10 @@ private ExpressionSyntax ParseSubExpressionCore(uint precedence)
{
var questionToken = this.EatToken();
var colonLeft = this.ParseSubExpression(nullCoalescingPrecedence - 1);
var colonLeft = this.ParseExpressionCore();
var colon = this.EatToken(SyntaxKind.ColonToken);
var colonRight = this.ParseSubExpression(nullCoalescingPrecedence - 1);
var colonRight = this.ParseExpressionCore();
leftOperand = _syntaxFactory.ConditionalExpression(leftOperand, questionToken, colonLeft, colon, colonRight);
}
......@@ -10193,11 +10193,16 @@ private bool IsQueryExpressionAfterFrom(bool mayBeVariableDeclaration, bool mayB
return false;
}
private QueryExpressionSyntax ParseQueryExpression()
private QueryExpressionSyntax ParseQueryExpression(uint precedence)
{
this.EnterQuery();
var fc = this.ParseFromClause();
fc = CheckFeatureAvailability(fc, MessageID.IDS_FeatureQueryExpression);
if (precedence > 1 && IsStrict)
{
fc = this.AddError(fc, ErrorCode.ERR_InvalidExprTerm, SyntaxFacts.GetText(SyntaxKind.FromKeyword));
}
var body = this.ParseQueryBody();
this.LeaveQuery();
return _syntaxFactory.QueryExpression(fc, body);
......@@ -10440,6 +10445,8 @@ private QueryContinuationSyntax ParseQueryContinuation()
return _syntaxFactory.QueryContinuation(@into, name, body);
}
private bool IsStrict => this.Options.Features.ContainsKey("strict");
[Obsolete("Use IsIncrementalAndFactoryContextMatches")]
private new bool IsIncremental
{
......
......@@ -1797,6 +1797,18 @@ static int Main()
return (errCount > 0) ? 1 : 0;
}
}";
// the grammar does not allow a query on the right-hand-side of &&, but we allow it except in strict mode.
CreateCompilationWithMscorlibAndSystemCore(source, parseOptions: TestOptions.Regular.WithFeature("strict", "true")).VerifyDiagnostics(
// (23,26): error CS1525: Invalid expression term 'from'
// var b = false && from x in src select x; // WRN CS0429
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "from x in src").WithArguments("from").WithLocation(23, 26),
// (4,1): hidden CS8019: Unnecessary using directive.
// using System.Collections.Generic;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System.Collections.Generic;").WithLocation(4, 1),
// (3,1): hidden CS8019: Unnecessary using directive.
// using System.Linq;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System.Linq;").WithLocation(3, 1)
);
CompileAndVerify(source, additionalRefs: new[] { LinqAssemblyRef },
expectedOutput: "0");
}
......
......@@ -508,6 +508,16 @@ public void TestConditional()
Assert.Equal("c", ts.WhenFalse.ToString());
}
[Fact]
public void TestConditional02()
{
// ensure that ?: has lower precedence than assignment.
var text = "a ? b=c : d=e";
var expr = this.ParseExpression(text);
Assert.Equal(SyntaxKind.ConditionalExpression, expr.Kind());
Assert.False(expr.HasErrors);
}
[Fact]
public void TestCast()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册