Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
8faa6685
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,发现更多精彩内容 >>
提交
8faa6685
编写于
3月 23, 2015
作者:
T
Tomas Matousek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix syntax associated with bound block of foreach
上级
1b93a724
变更
6
展开全部
隐藏空白更改
内联
并排
Showing
6 changed file
with
1049 addition
and
22 deletion
+1049
-22
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs
.../Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs
+31
-12
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenClosureLambdaTests.cs
...ers/CSharp/Test/Emit/CodeGen/CodeGenClosureLambdaTests.cs
+34
-1
src/Compilers/CSharp/Test/Emit/PDB/PDBLambdaTests.cs
src/Compilers/CSharp/Test/Emit/PDB/PDBLambdaTests.cs
+585
-0
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
...ures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
+391
-9
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
...s/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+2
-0
src/Features/CSharp/EditAndContinue/StatementSyntaxComparer.cs
...eatures/CSharp/EditAndContinue/StatementSyntaxComparer.cs
+6
-0
未找到文件。
src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs
浏览文件 @
8faa6685
...
...
@@ -125,6 +125,9 @@ private BoundStatement RewriteEnumeratorForEachStatement(BoundForEachStatement n
// V v = (V)(T)e.Current;
// /* node.Body */
// }
var
rewrittenBodyBlock
=
CreateBlockDeclaringIterationVariable
(
iterationVar
,
iterationVarDecl
,
rewrittenBody
,
forEachSyntax
);
BoundStatement
whileLoop
=
RewriteWhileStatement
(
syntax
:
forEachSyntax
,
rewrittenCondition
:
BoundCall
.
Synthesized
(
...
...
@@ -132,9 +135,7 @@ private BoundStatement RewriteEnumeratorForEachStatement(BoundForEachStatement n
receiverOpt
:
boundEnumeratorVar
,
method
:
enumeratorInfo
.
MoveNextMethod
),
conditionSequencePointSpan
:
forEachSyntax
.
InKeyword
.
Span
,
rewrittenBody
:
new
BoundBlock
(
rewrittenBody
.
Syntax
,
statements
:
ImmutableArray
.
Create
<
BoundStatement
>(
iterationVarDecl
,
rewrittenBody
),
locals
:
ImmutableArray
.
Create
<
LocalSymbol
>(
iterationVar
)),
rewrittenBody
:
rewrittenBodyBlock
,
breakLabel
:
node
.
BreakLabel
,
continueLabel
:
node
.
ContinueLabel
,
hasErrors
:
false
);
...
...
@@ -458,9 +459,8 @@ private BoundStatement RewriteStringForEachStatement(BoundForEachStatement node)
AddForEachIterationVariableSequencePoint
(
forEachSyntax
,
ref
iterationVarDecl
);
// { V v = (V)s.Chars[p]; /*node.Body*/ }
BoundStatement
loopBody
=
new
BoundBlock
(
forEachSyntax
,
locals
:
ImmutableArray
.
Create
<
LocalSymbol
>(
iterationVar
),
statements
:
ImmutableArray
.
Create
<
BoundStatement
>(
iterationVarDecl
,
rewrittenBody
));
BoundStatement
loopBody
=
CreateBlockDeclaringIterationVariable
(
iterationVar
,
iterationVarDecl
,
rewrittenBody
,
forEachSyntax
);
// for (string s = /*node.Expression*/, int p = 0; p < s.Length; p = p + 1) {
// V v = (V)s.Chars[p];
...
...
@@ -484,6 +484,27 @@ private BoundStatement RewriteStringForEachStatement(BoundForEachStatement node)
return
result
;
}
private
static
BoundBlock
CreateBlockDeclaringIterationVariable
(
LocalSymbol
iterationVariable
,
BoundStatement
iteratorVariableInitialization
,
BoundStatement
rewrittenBody
,
ForEachStatementSyntax
forEachSyntax
)
{
// The scope of the iteration variable is the embedded statement syntax.
// However consider the following foreach statement:
//
// foreach (int x in ...) { int y = ...; F(() => x); F(() => y));
//
// We currently generate 2 closures. One containing variable x, the other variable y.
// The EnC source mapping infrastructure requires each closure within a method body
// to have a unique syntax offset. Hence we associate the bound block declaring the
// iteration variable with the foreach statement, not the embedded statement.
return
new
BoundBlock
(
forEachSyntax
,
locals
:
ImmutableArray
.
Create
(
iterationVariable
),
statements
:
ImmutableArray
.
Create
(
iteratorVariableInitialization
,
rewrittenBody
));
}
/// <summary>
/// Lower a foreach loop that will enumerate a single-dimensional array.
///
...
...
@@ -583,10 +604,9 @@ private BoundStatement RewriteSingleDimensionalArrayForEachStatement(BoundForEac
BoundStatement
positionIncrement
=
MakePositionIncrement
(
forEachSyntax
,
boundPositionVar
,
intType
);
// { V v = (V)a[p]; /* node.Body */ }
BoundStatement
loopBody
=
new
BoundBlock
(
forEachSyntax
,
locals
:
ImmutableArray
.
Create
<
LocalSymbol
>(
iterationVar
),
statements
:
ImmutableArray
.
Create
<
BoundStatement
>(
iterationVariableDecl
,
rewrittenBody
));
BoundStatement
loopBody
=
CreateBlockDeclaringIterationVariable
(
iterationVar
,
iterationVariableDecl
,
rewrittenBody
,
forEachSyntax
);
// for (A[] a = /*node.Expression*/, int p = 0; p < a.Length; p = p + 1) {
// V v = (V)a[p];
// /*node.Body*/
...
...
@@ -714,9 +734,8 @@ private BoundStatement RewriteMultiDimensionalArrayForEachStatement(BoundForEach
AddForEachIterationVariableSequencePoint
(
forEachSyntax
,
ref
iterationVarDecl
);
// { V v = (V)a[p_0, p_1, ...]; /* node.Body */ }
BoundStatement
innermostLoopBody
=
new
BoundBlock
(
forEachSyntax
,
locals
:
ImmutableArray
.
Create
(
iterationVar
),
statements
:
ImmutableArray
.
Create
(
iterationVarDecl
,
rewrittenBody
));
BoundStatement
innermostLoopBody
=
CreateBlockDeclaringIterationVariable
(
iterationVar
,
iterationVarDecl
,
rewrittenBody
,
forEachSyntax
);
// work from most-nested to least-nested
// for (int p_0 = a.GetLowerBound(0); p_0 <= q_0; p_0 = p_0 + 1)
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenClosureLambdaTests.cs
浏览文件 @
8faa6685
...
...
@@ -5132,6 +5132,8 @@ static void Main(string[] args)
CompileAndVerify
(
source
);
}
#
endregion
[
Fact
]
public
void
LambdaInQuery_Let
()
{
...
...
@@ -5172,6 +5174,37 @@ public void F(int[] array)
CompileAndVerify
(
source
,
new
[]
{
SystemCoreRef
});
}
#
endregion
[
Fact
]
public
void
EmbeddedStatementClosures1
()
{
var
source
=
@"
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class C
{
public void G<T>(Func<T> f) {}
public void F()
{
for (int x = 1, y = 2; x < 10; x++) G(() => x + y);
for (int x = 1, y = 2; x < 10; x++) { G(() => x + y); }
foreach (var x in new[] { 1, 2, 3 }) G(() => x);
foreach (var x in new[] { 1, 2, 3 }) { G(() => x); }
foreach (var x in new[,] { {1}, {2}, {3} }) G(() => x);
foreach (var x in new[,] { {1}, {2}, {3} }) { G(() => x); }
foreach (var x in ""123"") G(() => x);
foreach (var x in ""123"") { G(() => x); }
foreach (var x in new List<string>()) G(() => x);
foreach (var x in new List<string>()) { G(() => x); }
using (var x = new MemoryStream()) G(() => x);
using (var x = new MemoryStream()) G(() => x);
}
}"
;
CompileAndVerify
(
source
,
new
[]
{
SystemCoreRef
});
}
}
}
src/Compilers/CSharp/Test/Emit/PDB/PDBLambdaTests.cs
浏览文件 @
8faa6685
此差异已折叠。
点击以展开。
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
浏览文件 @
8faa6685
...
...
@@ -1009,7 +1009,7 @@ public void CatchUpdate()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"Update [
catch (Exception e) { }]@10 -> [catch (IOException e) { }]@10
"
);
"Update [
(Exception e)]@16 -> [(IOException e)]@16
"
);
}
[
Fact
]
...
...
@@ -1022,6 +1022,7 @@ public void CatchInsert()
edits
.
VerifyEdits
(
"Insert [catch (IOException e) { /*3*/ }]@16"
,
"Insert [(IOException e)]@22"
,
"Insert [{ /*3*/ }]@38"
);
}
...
...
@@ -1047,6 +1048,7 @@ public void CatchDelete()
edits
.
VerifyEdits
(
"Delete [catch (Exception e) { }]@36"
,
"Delete [(Exception e)]@42"
,
"Delete [{ }]@56"
);
}
...
...
@@ -1073,7 +1075,7 @@ public void CatchReorder2()
edits
.
VerifyEdits
(
"Reorder [catch (Exception e) { }]@36 -> @26"
,
"Reorder [catch { }]@60 -> @10"
,
"
Update [catch { }]@60 -> [catch (A e) { }]@10
"
);
"
Insert [(A e)]@16
"
);
}
[
Fact
]
...
...
@@ -1105,8 +1107,10 @@ public void CatchInsertDelete()
edits
.
VerifyEdits
(
"Insert [catch (E e) { /*1*/ }]@79"
,
"Insert [(E e)]@85"
,
"Move [{ /*1*/ }]@29 -> @91"
,
"Delete [catch (E e) { /*1*/ }]@17"
);
"Delete [catch (E e) { /*1*/ }]@17"
,
"Delete [(E e)]@23"
);
}
[
Fact
]
...
...
@@ -1119,7 +1123,8 @@ public void Catch_DeleteHeader1()
edits
.
VerifyEdits
(
"Move [{ /*3*/ }]@52 -> @39"
,
"Delete [catch (E2 e) { /*3*/ }]@39"
);
"Delete [catch (E2 e) { /*3*/ }]@39"
,
"Delete [(E2 e)]@45"
);
}
[
Fact
]
...
...
@@ -1132,6 +1137,7 @@ public void Catch_InsertHeader1()
edits
.
VerifyEdits
(
"Insert [catch (E2 e) { /*3*/ }]@39"
,
"Insert [(E2 e)]@45"
,
"Move [{ /*3*/ }]@39 -> @52"
);
}
...
...
@@ -1182,7 +1188,7 @@ public void Catch_InsertFilter2()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"
Update [catch when (e == null) { /*2*/ }]@16 -> [catch (E1 e) when (e == null) { /*2*/ }]@16
"
);
"
Insert [(E1 e)]@22
"
);
}
[
Fact
]
...
...
@@ -1194,7 +1200,7 @@ public void Catch_InsertFilter3()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"
Update [catch { /*2*/ }]@16 -> [catch (E1 e) when (e == null) { /*2*/ }]@16
"
,
"
Insert [(E1 e)]@22
"
,
"Insert [when (e == null)]@29"
);
}
...
...
@@ -1207,7 +1213,7 @@ public void Catch_DeleteDeclaration1()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"
Update [catch (E1 e) { /*2*/ }]@16 -> [catch { /*2*/ }]@16
"
);
"
Delete [(E1 e)]@22
"
);
}
[
Fact
]
...
...
@@ -1231,7 +1237,7 @@ public void Catch_DeleteFilter2()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"
Update [catch (E1 e) when (e == null) { /*2*/ }]@16 -> [catch when (e == null) { /*2*/ }]@16
"
);
"
Delete [(E1 e)]@22
"
);
}
[
Fact
]
...
...
@@ -1243,7 +1249,7 @@ public void Catch_DeleteFilter3()
var
edits
=
GetMethodEdits
(
src1
,
src2
);
edits
.
VerifyEdits
(
"
Update [catch (E1 e) when (e == null) { /*2*/ }]@16 -> [catch { /*2*/ }]@16
"
,
"
Delete [(E1 e)]@22
"
,
"Delete [when (e == null)]@29"
);
}
...
...
@@ -2678,6 +2684,382 @@ void F()
Diagnostic
(
RudeEditKind
.
DeleteLambdaWithMultiScopeCapture
,
"x3"
,
CSharpFeaturesResources
.
Lambda
,
"this"
,
"x3"
));
}
[
Fact
]
public
void
Lambdas_Insert_ForEach1
()
{
var
src1
=
@"
using System;
class C
{
void G(Func<int, int> f) {}
void F()
{
foreach (int x0 in new[] { 1 }) // Group #0
{ // Group #1
int x1 = 0;
G(a => x0);
G(a => x1);
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
void G(Func<int, int> f) {}
void F()
{
foreach (int x0 in new[] { 1 }) // Group #0
{ // Group #1
int x1 = 0;
G(a => x0);
G(a => x1);
G(a => x0 + x1); // error: connecting previously disconnected closures
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x1"
,
"lambda"
,
"x0"
,
"x1"
));
}
[
Fact
]
public
void
Lambdas_Insert_ForEach2
()
{
var
src1
=
@"
using System;
class C
{
void G(Func<int, int> f1, Func<int, int> f2, Func<int, int> f3) {}
void F()
{
int x0 = 0; // Group #0
foreach (int x1 in new[] { 1 }) // Group #1
G(a => x0, a => x1, null);
}
}
"
;
var
src2
=
@"
using System;
class C
{
void G(Func<int, int> f1, Func<int, int> f2, Func<int, int> f3) {}
void F()
{
int x0 = 0; // Group #0
foreach (int x1 in new[] { 1 }) // Group #1
G(a => x0, a => x1, a => x0 + x1); // error: connecting previously disconnected closures
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x1"
,
"lambda"
,
"x0"
,
"x1"
));
}
[
Fact
]
public
void
Lambdas_Insert_For1
()
{
var
src1
=
@"
using System;
class C
{
bool G(Func<int, int> f) => true;
void F()
{
for (int x0 = 0, x1 = 0; G(a => x0) && G(a => x1);)
{
int x2 = 0;
G(a => x2);
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
bool G(Func<int, int> f) => true;
void F()
{
for (int x0 = 0, x1 = 0; G(a => x0) && G(a => x1);)
{
int x2 = 0;
G(a => x2);
G(a => x0 + x1); // ok
G(a => x0 + x2); // error: connecting previously disconnected closures
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x2"
,
"lambda"
,
"x0"
,
"x2"
));
}
[
Fact
]
public
void
Lambdas_Insert_Switch1
()
{
var
src1
=
@"
using System;
class C
{
bool G(Func<int> f) => true;
int a = 1;
void F()
{
int x2 = 1;
G(() => x2);
switch (a)
{
case 1:
int x0 = 1;
G(() => x0);
break;
case 2:
int x1 = 1;
G(() => x1);
break;
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
bool G(Func<int> f) => true;
int a = 1;
void F()
{
int x2 = 1;
G(() => x2);
switch (a)
{
case 1:
int x0 = 1;
G(() => x0);
goto case 2;
case 2:
int x1 = 1;
G(() => x1);
goto default;
default:
x0 = 1;
x1 = 2;
G(() => x0 + x1); // ok
G(() => x0 + x2); // error
break;
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x0"
,
"lambda"
,
"x2"
,
"x0"
));
}
[
Fact
]
public
void
Lambdas_Insert_Using1
()
{
var
src1
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static int F(object a, object b) => 1;
static IDisposable D() => null;
static void F()
{
using (IDisposable x0 = D(), y0 = D())
{
int x1 = 1;
G(() => x0);
G(() => y0);
G(() => x1);
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static int F(object a, object b) => 1;
static IDisposable D() => null;
static void F()
{
using (IDisposable x0 = D(), y0 = D())
{
int x1 = 1;
G(() => x0);
G(() => y0);
G(() => x1);
G(() => F(x0, y0)); // ok
G(() => F(x0, x1)); // error
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x1"
,
"lambda"
,
"x0"
,
"x1"
));
}
[
Fact
]
public
void
Lambdas_Insert_Catch1
()
{
var
src1
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static int F(object a, object b) => 1;
static void F()
{
try
{
}
catch (Exception x0)
{
int x1 = 1;
G(() => x0);
G(() => x1);
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static int F(object a, object b) => 1;
static void F()
{
try
{
}
catch (Exception x0)
{
int x1 = 1;
G(() => x0);
G(() => x1);
G(() => x0); //ok
G(() => F(x0, x1)); //error
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
InsertLambdaWithMultiScopeCapture
,
"x1"
,
"lambda"
,
"x0"
,
"x1"
));
}
[
Fact
(
Skip
=
"https://github.com/dotnet/roslyn/issues/1504"
),
WorkItem
(
1504
)]
public
void
Lambdas_Insert_CatchFilter1
()
{
var
src1
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static void F()
{
Exception x1 = null;
try
{
G(() => x1);
}
catch (Exception x0) when (G(() => x0))
{
}
}
}
"
;
var
src2
=
@"
using System;
class C
{
static bool G<T>(Func<T> f) => true;
static void F()
{
Exception x1 = null;
try
{
G(() => x1);
}
catch (Exception x0) when (G(() => x0) &&
G(() => x0) && // ok
G(() => x0 != x1)) // error
{
G(() => x0); // ok
}
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
();
}
[
Fact
]
public
void
Lambdas_Update_CeaseCapture_This
()
{
...
...
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
浏览文件 @
8faa6685
...
...
@@ -1079,6 +1079,7 @@ internal static TextSpan GetDiagnosticSpanImpl(SyntaxKind kind, SyntaxNode node,
case
SyntaxKind
.
CatchClause
:
return
((
CatchClauseSyntax
)
node
).
CatchKeyword
.
Span
;
case
SyntaxKind
.
CatchDeclaration
:
case
SyntaxKind
.
CatchFilterClause
:
return
node
.
Span
;
...
...
@@ -1343,6 +1344,7 @@ internal static string GetStatementDisplayNameImpl(SyntaxNode node)
return
CSharpFeaturesResources
.
TryBlock
;
case
SyntaxKind
.
CatchClause
:
case
SyntaxKind
.
CatchDeclaration
:
return
CSharpFeaturesResources
.
CatchClause
;
case
SyntaxKind
.
CatchFilterClause
:
...
...
src/Features/CSharp/EditAndContinue/StatementSyntaxComparer.cs
浏览文件 @
8faa6685
...
...
@@ -157,6 +157,7 @@ internal enum Label
TryStatement
,
CatchClause
,
// tied to parent
CatchDeclaration
,
// tied to parent
CatchFilterClause
,
// tied to parent
FinallyClause
,
// tied to parent
ForStatement
,
...
...
@@ -223,6 +224,7 @@ private static int TiedToAncestor(Label label)
case
Label
.
BreakContinueStatement
:
case
Label
.
ElseClause
:
case
Label
.
CatchClause
:
case
Label
.
CatchDeclaration
:
case
Label
.
CatchFilterClause
:
case
Label
.
FinallyClause
:
case
Label
.
ForStatementPart
:
...
...
@@ -366,6 +368,10 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL
case
SyntaxKind
.
CatchClause
:
return
Label
.
CatchClause
;
case
SyntaxKind
.
CatchDeclaration
:
// the declarator of the exception variable
return
Label
.
CatchDeclaration
;
case
SyntaxKind
.
CatchFilterClause
:
return
Label
.
CatchFilterClause
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录