-
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
Move feature check from lexer to binder. #57113
Conversation
@@ -18,6 +18,10 @@ internal partial class Binder | |||
{ | |||
private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSyntax node, BindingDiagnosticBag diagnostics) | |||
{ | |||
var startText = node.StringStartToken.Text; | |||
if (startText.StartsWith("@$\"")) | |||
CheckFeatureAvailability(node, MessageID.IDS_FeatureAltInterpolatedVerbatimStrings, diagnostics, node.StringStartToken.GetLocation()); |
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.
one single check in one location.
if (feature == MessageID.IDS_FeatureAltInterpolatedVerbatimStrings) | ||
{ | ||
return new CSDiagnosticInfo(ErrorCode.ERR_AltInterpolatedVerbatimStringsNotAvailable, new CSharpRequiredLanguageVersion(feature.RequiredVersion())); | ||
} |
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.
preserves the special error message we give here (the parser used to special case this as well).
if (isAltInterpolatedVerbatim) | ||
{ | ||
openQuote = CheckFeatureAvailability(openQuote, MessageID.IDS_FeatureAltInterpolatedVerbatimStrings); | ||
} |
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.
parser check.
@@ -771,7 +771,6 @@ private void ScanSyntaxToken(ref TokenInfo info) | |||
else if (TextWindow.PeekChar(1) == '$' && TextWindow.PeekChar(2) == '"') | |||
{ | |||
this.ScanInterpolatedStringLiteral(isVerbatim: true, ref info); | |||
CheckFeatureAvailability(MessageID.IDS_FeatureAltInterpolatedVerbatimStrings); |
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.
lexer check #1. intended to be overridden by parser.
@@ -628,7 +628,6 @@ private void ScanInterpolatedStringLiteralHoleBalancedText(char endingChar, bool | |||
} | |||
else if (_lexer.TextWindow.PeekChar(1) == '$' && _lexer.TextWindow.PeekChar(2) == '"') | |||
{ | |||
_lexer.CheckFeatureAvailability(MessageID.IDS_FeatureAltInterpolatedVerbatimStrings); |
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.
lexer check #2, during recursive interpolated string lexing. Intended to be overridden by parser.
return availableVersion >= requiredVersion | ||
? node | ||
: this.AddError(node, ErrorCode.ERR_AltInterpolatedVerbatimStringsNotAvailable, | ||
new CSharpRequiredLanguageVersion(requiredVersion)); |
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.
special case error message. moved to https://github.com/dotnet/roslyn/pull/57113/files#diff-a1cb0e0d2615ca34e6c6cfc96a0300cb85c046ca6f90bf0d8931021ec8ccc480R334
src/Compilers/CSharp/Portable/Binder/Binder_InterpolatedString.cs
Outdated
Show resolved
Hide resolved
e22c1a1
to
267fc94
Compare
@dotnet/roslyn-compiler @jcouv for another set of eyes. Thanks! |
Thanks! |
Please remember to squash compiler changes. Thanks |
Note: this is not part of more work to do this in other locations.
This change is very specific as the way this current check works is complex, difficult to sustain for raw-string-literals, and also (IMO) violates how the lexer/parser should work.
Specifically, the lexer, today, needs to recurse back into itself when dealing with interpolated string literals. It does this both at lex time (to make the initial token and figure out interpolation boundaries), and it then does it again when teh parser comes in and makes the real InterpolationExpressionSyntax. As such, it is both confusing, and error-prone for errors to be added here in the interpolation holes as both the lexer and parser take over the same responsibility. Indeed, it is necessary for these lexer errors to not bubble up as they must get reported now by the parser. This complicates lexing (esp. interpolation lexing) by effectively making it so that some errors are reported internally, but not bubbled up. And some errors are reported internally, stored, and bubbled up to the parser.
I do not want to try to maintain/duplicate that conceptual complexity. As such, i'm moving this logic entirely to the binder. This has the benefit of reverse-smearing things. What was three checks, with a complex relation betwen them, becomes one simple check.