-
Notifications
You must be signed in to change notification settings - Fork 4k
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
return, break and continue expressions #20269
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -622,6 +622,15 @@ private BoundExpression BindExpressionInternal(ExpressionSyntax node, Diagnostic | |
case SyntaxKind.ThrowExpression: | ||
return BindThrowExpression((ThrowExpressionSyntax)node, diagnostics); | ||
|
||
case SyntaxKind.ReturnExpression: | ||
return BindReturnExpression((ReturnExpressionSyntax)node, diagnostics); | ||
|
||
case SyntaxKind.BreakExpression: | ||
return BindBreakExpression((BreakExpressionSyntax)node, diagnostics); | ||
|
||
case SyntaxKind.ContinueExpression: | ||
return BindContinueExpression((ContinueExpressionSyntax)node, diagnostics); | ||
|
||
case SyntaxKind.RefType: | ||
return BindRefType(node, diagnostics); | ||
|
||
|
@@ -661,6 +670,78 @@ private BoundExpression BindRefType(ExpressionSyntax node, DiagnosticBag diagnos | |
return new BoundTypeExpression(node, null, CreateErrorType("ref")); | ||
} | ||
|
||
private BoundExpression BindReturnExpression(ReturnExpressionSyntax node, DiagnosticBag diagnostics) | ||
{ | ||
bool hasErrors = false; | ||
if (!IsJumpExpressionInProperContext(node)) | ||
{ | ||
diagnostics.Add(ErrorCode.ERR_ThrowMisplaced, node.ReturnKeyword.GetLocation()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could I change |
||
hasErrors = true; | ||
} | ||
|
||
BoundExpression arg = BindReturnedExpression(node, node.Expression, node.ReturnKeyword, diagnostics, out RefKind refKind, out bool hadErrors); | ||
return new BoundReturnExpression(node, refKind, arg, type: null, hasErrors: hasErrors || hadErrors); | ||
} | ||
|
||
private BoundExpression BindContinueExpression(ContinueExpressionSyntax node, DiagnosticBag diagnostics) | ||
{ | ||
bool hasErrors = node.HasErrors; | ||
if (!IsJumpExpressionInProperContext(node)) | ||
{ | ||
diagnostics.Add(ErrorCode.ERR_ThrowMisplaced, node.ContinueKeyword.GetLocation()); | ||
hasErrors = true; | ||
} | ||
|
||
var label = this.ContinueLabel; | ||
if ((object)label == null) | ||
{ | ||
Error(diagnostics, ErrorCode.ERR_NoBreakOrCont, node); | ||
return BadExpression(node); | ||
} | ||
|
||
return new BoundContinueExpression(node, label, type: null, hasErrors: hasErrors); | ||
} | ||
|
||
private BoundExpression BindBreakExpression(BreakExpressionSyntax node, DiagnosticBag diagnostics) | ||
{ | ||
bool hasErrors = node.HasErrors; | ||
if (!IsJumpExpressionInProperContext(node)) | ||
{ | ||
diagnostics.Add(ErrorCode.ERR_ThrowMisplaced, node.BreakKeyword.GetLocation()); | ||
hasErrors = true; | ||
} | ||
|
||
var label = this.BreakLabel; | ||
if ((object)label == null) | ||
{ | ||
Error(diagnostics, ErrorCode.ERR_NoBreakOrCont, node); | ||
return BadExpression(node); | ||
} | ||
|
||
return new BoundBreakExpression(node, label, type: null, hasErrors: hasErrors); | ||
} | ||
|
||
private static bool IsJumpExpressionInProperContext(ExpressionSyntax node) | ||
{ | ||
var parent = node.Parent; | ||
if (parent == null || node.HasErrors) | ||
{ | ||
return true; | ||
} | ||
|
||
switch (node.Parent.Kind()) | ||
{ | ||
case SyntaxKind.ConditionalExpression: | ||
var conditionalParent = (ConditionalExpressionSyntax)parent; | ||
return node == conditionalParent.WhenTrue || node == conditionalParent.WhenFalse; | ||
case SyntaxKind.CoalesceExpression: | ||
var binaryParent = (BinaryExpressionSyntax)parent; | ||
return node == binaryParent.Right; | ||
default: | ||
return false; | ||
} | ||
} | ||
|
||
private BoundExpression BindThrowExpression(ThrowExpressionSyntax node, DiagnosticBag diagnostics) | ||
{ | ||
bool hasErrors = node.HasErrors; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ internal enum ConversionKind : byte | |
ImplicitNumeric, | ||
ImplicitEnumeration, | ||
ImplicitThrow, | ||
ImplicitJump, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we merge |
||
ImplicitTupleLiteral, | ||
ImplicitTuple, | ||
ExplicitTupleLiteral, | ||
|
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.
This is disabled to make return-expression's expression optional; , otherwise it complains about the default parameter. (bug?)