提交 f6cd1b07 编写于 作者: N nmgafter

1099238-Lost lexical errors from literal parts of interpolated strings (changeset 1395214)

上级 d57807dd
......@@ -189,24 +189,35 @@ private InterpolationSyntax ParseInterpolation(string text, Lexer.Interpolation
/// <param name="kind">The token kind to be assigned to the resulting token</param>
SyntaxToken MakeStringToken(string text, string bodyText, bool isVerbatim, SyntaxKind kind)
{
var fakeString = (isVerbatim ? "@\"" : "\"") + bodyText + "\"";
var prefix = isVerbatim ? "@\"" : "\"";
var fakeString = prefix + bodyText + "\"";
using (var tempLexer = new Lexer(Text.SourceText.From(fakeString), this.Options, allowPreprocessorDirectives: false))
{
var info = default(Lexer.TokenInfo);
if (isVerbatim)
{
tempLexer.ScanVerbatimStringLiteral(ref info);
}
else
LexerMode mode = LexerMode.Syntax;
SyntaxToken token = tempLexer.Lex(ref mode);
Debug.Assert(token.Kind == SyntaxKind.StringLiteralToken);
var result = SyntaxFactory.Literal(null, text, kind, token.ValueText, null);
if (token.ContainsDiagnostics)
{
tempLexer.ScanStringLiteral(ref info);
result = result.WithDiagnosticsGreen(MoveDiagnostics(token.GetDiagnostics(), -prefix.Length));
}
Debug.Assert(info.Kind == SyntaxKind.StringLiteralToken);
return SyntaxFactory.Literal(null, text, kind, info.StringValue, null);
return result;
}
}
DiagnosticInfo[] MoveDiagnostics(DiagnosticInfo[] infos, int offset)
{
var builder = ArrayBuilder<DiagnosticInfo>.GetInstance();
foreach (var info in infos)
{
var sd = info as SyntaxDiagnosticInfo;
builder.Add(sd?.WithOffset(sd.Offset + offset) ?? info);
}
return builder.ToArrayAndFree();
}
private void ParseInterpolationStart(out SyntaxToken openBraceToken, out ExpressionSyntax expr, out SyntaxToken commaToken, out ExpressionSyntax alignmentExpression)
{
openBraceToken = this.EatToken(SyntaxKind.OpenBraceToken);
......
......@@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax
{
internal partial class Lexer
{
internal void ScanStringLiteral(ref TokenInfo info, bool allowEscapes = true)
private void ScanStringLiteral(ref TokenInfo info, bool allowEscapes = true)
{
var quoteCharacter = TextWindow.PeekChar();
if (quoteCharacter == '\'' || quoteCharacter == '"')
......@@ -151,7 +151,7 @@ private char ScanEscapeSequence(out char surrogateCharacter)
return ch;
}
internal void ScanVerbatimStringLiteral(ref TokenInfo info, bool allowNewlines = true)
private void ScanVerbatimStringLiteral(ref TokenInfo info, bool allowNewlines = true)
{
this.builder.Length = 0;
......
......@@ -1018,7 +1018,10 @@ static void Main(string[] args)
CreateCompilationWithMscorlib(text).VerifyDiagnostics(
// (6,40): error CS8087: A '}' character may only be escaped by doubling '}}' in an interpolated string.
// var x = $"{ Math.Abs(value: 1):\}";
Diagnostic(ErrorCode.ERR_EscapedCurly, @"\").WithArguments("}").WithLocation(6, 40)
Diagnostic(ErrorCode.ERR_EscapedCurly, @"\").WithArguments("}").WithLocation(6, 40),
// (6,40): error CS1009: Unrecognized escape sequence
// var x = $"{ Math.Abs(value: 1):\}";
Diagnostic(ErrorCode.ERR_IllegalEscape, @"\}").WithLocation(6, 40)
);
}
......@@ -1106,5 +1109,31 @@ public void Dynamic01()
);
}
[WorkItem(1099238, "DevDiv")]
[Fact]
public void Syntax04()
{
var text =
@"using System;
using System.Linq.Expressions;
class Program
{
static void Main()
{
Expression<Func<string>> e = () => $""\u1{0:\u2}"";
Console.WriteLine(e);
}
}";
CreateCompilationWithMscorlibAndSystemCore(text).VerifyDiagnostics(
// (8,46): error CS1009: Unrecognized escape sequence
// Expression<Func<string>> e = () => $"\u1{0:\u2}";
Diagnostic(ErrorCode.ERR_IllegalEscape, @"\u1").WithLocation(8, 46),
// (8,52): error CS1009: Unrecognized escape sequence
// Expression<Func<string>> e = () => $"\u1{0:\u2}";
Diagnostic(ErrorCode.ERR_IllegalEscape, @"\u2").WithLocation(8, 52)
);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册