提交 bbf380be 编写于 作者: A Alireza Habibi 提交者: Julien Couvreur

Fix bug when trailing and leading underscores are not the same (#22141)

Merging on behalf of @alrz. Thanks
上级 7ee07eac
......@@ -933,9 +933,8 @@ private bool ScanInteger()
}
// Allows underscores in integers, except at beginning for decimal and end
private void ScanNumericLiteralSingleInteger(ref bool underscoreInWrongPlace, ref bool usedUnderscore, bool isHex, bool isBinary)
private void ScanNumericLiteralSingleInteger(ref bool underscoreInWrongPlace, ref bool usedUnderscore, ref bool firstCharWasUnderscore, bool isHex, bool isBinary)
{
bool firstCharWasUnderscore = false;
if (TextWindow.PeekChar() == '_')
{
if (isHex || isBinary)
......@@ -971,13 +970,7 @@ private void ScanNumericLiteralSingleInteger(ref bool underscoreInWrongPlace, re
TextWindow.AdvanceChar();
}
if (firstCharWasUnderscore)
{
CheckFeatureAvailability(MessageID.IDS_FeatureLeadingDigitSeparator);
// No need for cascading feature error
usedUnderscore = false;
}
else if (lastCharWasUnderscore)
if (lastCharWasUnderscore)
{
underscoreInWrongPlace = true;
}
......@@ -998,6 +991,7 @@ private bool ScanNumericLiteral(ref TokenInfo info)
bool hasLSuffix = false;
bool underscoreInWrongPlace = false;
bool usedUnderscore = false;
bool firstCharWasUnderscore = false;
ch = TextWindow.PeekChar();
if (ch == '0')
......@@ -1020,7 +1014,7 @@ private bool ScanNumericLiteral(ref TokenInfo info)
{
// It's OK if it has no digits after the '0x' -- we'll catch it in ScanNumericLiteral
// and give a proper error then.
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, isHex, isBinary);
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, ref firstCharWasUnderscore, isHex, isBinary);
if ((ch = TextWindow.PeekChar()) == 'L' || ch == 'l')
{
......@@ -1050,7 +1044,7 @@ private bool ScanNumericLiteral(ref TokenInfo info)
}
else
{
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, isHex: false, isBinary: false);
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, ref firstCharWasUnderscore, isHex: false, isBinary: false);
if (this.ModeIs(LexerMode.DebuggerSyntax) && TextWindow.PeekChar() == '#')
{
......@@ -1071,7 +1065,7 @@ private bool ScanNumericLiteral(ref TokenInfo info)
_builder.Append(ch);
TextWindow.AdvanceChar();
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, isHex: false, isBinary: false);
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, ref firstCharWasUnderscore, isHex: false, isBinary: false);
}
else if (_builder.Length == 0)
{
......@@ -1102,7 +1096,7 @@ private bool ScanNumericLiteral(ref TokenInfo info)
}
else
{
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, isHex: false, isBinary: false);
ScanNumericLiteralSingleInteger(ref underscoreInWrongPlace, ref usedUnderscore, ref firstCharWasUnderscore, isHex: false, isBinary: false);
}
}
......@@ -1174,7 +1168,11 @@ private bool ScanNumericLiteral(ref TokenInfo info)
{
this.AddError(MakeError(start, TextWindow.Position - start, ErrorCode.ERR_InvalidNumber));
}
if (usedUnderscore)
else if (firstCharWasUnderscore)
{
CheckFeatureAvailability(MessageID.IDS_FeatureLeadingDigitSeparator);
}
else if (usedUnderscore)
{
CheckFeatureAvailability(MessageID.IDS_FeatureDigitSeparator);
}
......@@ -1198,7 +1196,10 @@ private bool ScanNumericLiteral(ref TokenInfo info)
default:
if (string.IsNullOrEmpty(valueText))
{
this.AddError(MakeError(ErrorCode.ERR_InvalidNumber));
if (!underscoreInWrongPlace)
{
this.AddError(MakeError(ErrorCode.ERR_InvalidNumber));
}
val = 0; //safe default
}
else
......
......@@ -2815,6 +2815,17 @@ public void TestNumericWithBadUnderscores()
Assert.Equal("error CS1013: Invalid number", errors[0].ToString(EnsureEnglishUICulture.PreferredOrNull));
Assert.Equal(text, token.Text);
text = "0x_2_";
token = LexToken(text, _options72);
Assert.NotNull(token);
Assert.Equal(SyntaxKind.NumericLiteralToken, token.Kind());
errors = token.Errors();
Assert.Equal(1, errors.Length);
Assert.Equal((int)ErrorCode.ERR_InvalidNumber, errors[0].Code);
Assert.Equal("error CS1013: Invalid number", errors[0].ToString(EnsureEnglishUICulture.PreferredOrNull));
Assert.Equal(text, token.Text);
text = "1E+_2";
token = LexToken(text, _options72);
......
......@@ -1298,6 +1298,14 @@ End If]]>.Value,
Assert.Equal(1, errors.Count)
Assert.Equal(30035, errors.First().Code)
Assert.Equal(0, CInt(tk.Value))
Str = "&H_2_"
tk = ScanOnce(Str)
Assert.Equal(SyntaxKind.IntegerLiteralToken, tk.Kind)
errors = tk.Errors()
Assert.Equal(1, errors.Count)
Assert.Equal(30035, errors.First().Code)
Assert.Equal(0, CInt(tk.Value))
End Sub
<Fact>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册