Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
2a58f734
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
2a58f734
编写于
6月 07, 2020
作者:
N
Neal Gafter
提交者:
GitHub
6月 07, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
When there is an error in an interpolated string, take the next quote as a close quote (#44899)
Fixes #44789
上级
896ac93c
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
134 addition
and
9 deletion
+134
-9
src/Compilers/CSharp/Portable/Parser/Lexer_StringLiteral.cs
src/Compilers/CSharp/Portable/Parser/Lexer_StringLiteral.cs
+19
-1
src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs
...lers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs
+2
-8
src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs
...lers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs
+113
-0
未找到文件。
src/Compilers/CSharp/Portable/Parser/Lexer_StringLiteral.cs
浏览文件 @
2a58f734
...
@@ -372,6 +372,12 @@ private void ScanInterpolatedStringLiteralContents(ArrayBuilder<Interpolation> i
...
@@ -372,6 +372,12 @@ private void ScanInterpolatedStringLiteralContents(ArrayBuilder<Interpolation> i
switch
(
lexer
.
TextWindow
.
PeekChar
())
switch
(
lexer
.
TextWindow
.
PeekChar
())
{
{
case
'"'
when
RecoveringFromRunawayLexing
():
// When recovering from mismatched delimiters, we consume the next
// quote character as the close quote for the interpolated string. In
// practice this gets us out of trouble in scenarios we've encountered.
// See, for example, https://github.com/dotnet/roslyn/issues/44789
return
;
case
'"'
:
case
'"'
:
if
(
isVerbatim
&&
lexer
.
TextWindow
.
PeekChar
(
1
)
==
'"'
)
if
(
isVerbatim
&&
lexer
.
TextWindow
.
PeekChar
(
1
)
==
'"'
)
{
{
...
@@ -588,13 +594,19 @@ private void ScanInterpolatedStringLiteralHoleBalancedText(char endingChar, bool
...
@@ -588,13 +594,19 @@ private void ScanInterpolatedStringLiteralHoleBalancedText(char endingChar, bool
}
}
goto
default
;
goto
default
;
case
'"'
when
RecoveringFromRunawayLexing
():
// When recovering from mismatched delimiters, we consume the next
// quote character as the close quote for the interpolated string. In
// practice this gets us out of trouble in scenarios we've encountered.
// See, for example, https://github.com/dotnet/roslyn/issues/44789
return
;
case
'"'
:
case
'"'
:
case
'\''
:
case
'\''
:
// handle string or character literal inside an expression hole.
// handle string or character literal inside an expression hole.
ScanInterpolatedStringLiteralNestedString
();
ScanInterpolatedStringLiteralNestedString
();
continue
;
continue
;
case
'@'
:
case
'@'
:
if
(
lexer
.
TextWindow
.
PeekChar
(
1
)
==
'"'
)
if
(
lexer
.
TextWindow
.
PeekChar
(
1
)
==
'"'
&&
!
RecoveringFromRunawayLexing
()
)
{
{
// check for verbatim string inside an expression hole.
// check for verbatim string inside an expression hole.
ScanInterpolatedStringLiteralNestedVerbatimString
();
ScanInterpolatedStringLiteralNestedVerbatimString
();
...
@@ -655,6 +667,12 @@ private void ScanInterpolatedStringLiteralHoleBalancedText(char endingChar, bool
...
@@ -655,6 +667,12 @@ private void ScanInterpolatedStringLiteralHoleBalancedText(char endingChar, bool
}
}
}
}
/// <summary>
/// The lexer can run away consuming the rest of the input when delimiters are mismatched.
/// This is a test for when we are attempting to recover from that situation.
/// </summary>
private
bool
RecoveringFromRunawayLexing
()
=>
this
.
error
!=
null
;
private
void
ScanInterpolatedStringLiteralNestedComment
()
private
void
ScanInterpolatedStringLiteralNestedComment
()
{
{
Debug
.
Assert
(
lexer
.
TextWindow
.
PeekChar
()
==
'/'
);
Debug
.
Assert
(
lexer
.
TextWindow
.
PeekChar
()
==
'/'
);
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs
浏览文件 @
2a58f734
...
@@ -151,14 +151,8 @@ public static void Main(string[] args)
...
@@ -151,14 +151,8 @@ public static void Main(string[] args)
// too many diagnostics perhaps, but it starts the right way.
// too many diagnostics perhaps, but it starts the right way.
CreateCompilationWithMscorlib45
(
source
).
VerifyDiagnostics
(
CreateCompilationWithMscorlib45
(
source
).
VerifyDiagnostics
(
// (5,71): error CS8077: A single-line comment may not be used in an interpolated string.
// (5,71): error CS8077: A single-line comment may not be used in an interpolated string.
// Console.WriteLine("Jenny don\'t change your number \{ 8675309 // ");
// Console.WriteLine($"Jenny don\'t change your number { 8675309 // ");
Diagnostic
(
ErrorCode
.
ERR_SingleLineCommentInExpressionHole
,
"//"
).
WithLocation
(
5
,
71
),
Diagnostic
(
ErrorCode
.
ERR_SingleLineCommentInExpressionHole
,
"//"
).
WithLocation
(
5
,
71
)
// (5,77): error CS1026: ) expected
// Console.WriteLine("Jenny don\'t change your number \{ 8675309 // ");
Diagnostic
(
ErrorCode
.
ERR_CloseParenExpected
,
""
).
WithLocation
(
5
,
77
),
// (5,77): error CS1002: ; expected
// Console.WriteLine("Jenny don\'t change your number \{ 8675309 // ");
Diagnostic
(
ErrorCode
.
ERR_SemicolonExpected
,
""
).
WithLocation
(
5
,
77
)
);
);
}
}
...
...
src/Compilers/CSharp/Test/Syntax/Parsing/ExpressionParsingTests.cs
浏览文件 @
2a58f734
...
@@ -5236,5 +5236,118 @@ public void ArrayCreation_ElementAccess()
...
@@ -5236,5 +5236,118 @@ public void ArrayCreation_ElementAccess()
}
}
EOF
();
EOF
();
}
}
[
Fact
,
WorkItem
(
44789
,
"https://github.com/dotnet/roslyn/issues/44789"
)]
public
void
MismatchedInterpolatedStringContents_01
()
{
var
text
=
@"class A
{
void M()
{
if (b)
{
A B = new C($@""{D(.E}"");
N.O("""", P.Q);
R.S(T);
U.V(W.X, Y.Z);
}
}
string M() => """";
}"
;
var
tree
=
ParseTree
(
text
,
TestOptions
.
Regular
);
// Note that the parser eventually syncs back up and stops producing diagnostics.
tree
.
GetDiagnostics
().
Verify
(
// (7,31): error CS1001: Identifier expected
// A B = new C($@"{D(.E}");
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
"."
).
WithLocation
(
7
,
31
),
// (7,33): error CS1003: Syntax error, ')' expected
// A B = new C($@"{D(.E}");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"}"
).
WithArguments
(
")"
).
WithLocation
(
7
,
33
),
// (7,33): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"}"
).
WithArguments
(
","
,
"}"
).
WithLocation
(
7
,
33
),
// (7,34): error CS1026: ) expected
// A B = new C($@"{D(.E}");
Diagnostic
(
ErrorCode
.
ERR_CloseParenExpected
,
""
).
WithLocation
(
7
,
34
)
);
}
[
Fact
,
WorkItem
(
44789
,
"https://github.com/dotnet/roslyn/issues/44789"
)]
public
void
MismatchedInterpolatedStringContents_02
()
{
var
text
=
@"class A
{
void M()
{
if (b)
{
A B = new C($@""{D(.E}\F\G{H}_{I.J.K(""L"")}.M"");
N.O("""", P.Q);
R.S(T);
U.V(W.X, Y.Z);
}
}
string M() => """";
}"
;
var
tree
=
ParseTree
(
text
,
TestOptions
.
Regular
);
// Note that the parser eventually syncs back up and stops producing diagnostics.
tree
.
GetDiagnostics
().
Verify
(
// (7,31): error CS1001: Identifier expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_IdentifierExpected
,
"."
).
WithLocation
(
7
,
31
),
// (7,33): error CS1003: Syntax error, ')' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"}"
).
WithArguments
(
")"
).
WithLocation
(
7
,
33
),
// (7,33): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"}"
).
WithArguments
(
","
,
"}"
).
WithLocation
(
7
,
33
),
// (7,34): error CS1056: Unexpected character '\'
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_UnexpectedCharacter
,
""
).
WithArguments
(
"\\"
).
WithLocation
(
7
,
34
),
// (7,35): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"F"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
35
),
// (7,36): error CS1056: Unexpected character '\'
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_UnexpectedCharacter
,
""
).
WithArguments
(
"\\"
).
WithLocation
(
7
,
36
),
// (7,37): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"G"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
37
),
// (7,38): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"{"
).
WithArguments
(
","
,
"{"
).
WithLocation
(
7
,
38
),
// (7,39): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"H"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
39
),
// (7,40): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"}"
).
WithArguments
(
","
,
"}"
).
WithLocation
(
7
,
40
),
// (7,41): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"_"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
41
),
// (7,42): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"{"
).
WithArguments
(
","
,
"{"
).
WithLocation
(
7
,
42
),
// (7,43): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"I"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
43
),
// (7,49): error CS1026: ) expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_CloseParenExpected
,
""
).
WithLocation
(
7
,
49
),
// (7,49): error CS1026: ) expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_CloseParenExpected
,
""
).
WithLocation
(
7
,
49
),
// (7,50): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
"L"
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
50
),
// (7,51): error CS1003: Syntax error, ',' expected
// A B = new C($@"{D(.E}\F\G{H}_{I.J.K("L")}.M");
Diagnostic
(
ErrorCode
.
ERR_SyntaxError
,
@""")}.M"""
).
WithArguments
(
","
,
""
).
WithLocation
(
7
,
51
)
);
}
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录