Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
c90f3a12
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,发现更多精彩内容 >>
提交
c90f3a12
编写于
3月 10, 2015
作者:
T
Tomas Matousek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement EnC support for range variables in C# queries, improve query clause matching
上级
9c9a01d7
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
1255 addition
and
161 deletion
+1255
-161
src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
+4
-1
src/Compilers/CSharp/Portable/Syntax/SyntaxUtilities.cs
src/Compilers/CSharp/Portable/Syntax/SyntaxUtilities.cs
+0
-4
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.cs
.../Emit/Emit/EditAndContinue/EditAndContinueClosureTests.cs
+416
-0
src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
...atures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
+105
-12
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
...ures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
+276
-39
src/EditorFeatures/Test/EditAndContinue/Extensions.cs
src/EditorFeatures/Test/EditAndContinue/Extensions.cs
+1
-1
src/Features/CSharp/CSharpFeatures.csproj
src/Features/CSharp/CSharpFeatures.csproj
+2
-2
src/Features/CSharp/CSharpFeaturesResources.Designer.cs
src/Features/CSharp/CSharpFeaturesResources.Designer.cs
+207
-0
src/Features/CSharp/CSharpFeaturesResources.resx
src/Features/CSharp/CSharpFeaturesResources.resx
+69
-0
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
...s/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+44
-23
src/Features/CSharp/EditAndContinue/StatementSyntaxComparer.cs
...eatures/CSharp/EditAndContinue/StatementSyntaxComparer.cs
+77
-65
src/Features/CSharp/EditAndContinue/SyntaxUtilities.cs
src/Features/CSharp/EditAndContinue/SyntaxUtilities.cs
+17
-4
src/Features/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
...s/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
+37
-10
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Query.cs
浏览文件 @
c90f3a12
...
...
@@ -590,7 +590,10 @@ private void ReduceLet(LetClauseSyntax let, QueryTranslationState state, Diagnos
}
var
construction
=
MakePair
(
let
,
x
.
Name
,
xExpression
,
let
.
Identifier
.
ValueText
,
yExpression
,
state
,
d
);
return
lambdaBodyBinder
.
CreateBlockFromExpression
(
let
,
lambdaBodyBinder
.
Locals
,
null
,
construction
,
d
);
// The bound block represents a closure scope for transparent identifiers captured in the let clause.
// Such closures shall be associated with the lambda body expression.
return
lambdaBodyBinder
.
CreateBlockFromExpression
(
let
.
Expression
,
lambdaBodyBinder
.
Locals
,
null
,
construction
,
d
);
};
var
lambda
=
MakeQueryUnboundLambda
(
state
.
RangeVariableMap
(),
ImmutableArray
.
Create
(
x
),
let
.
Expression
,
bodyFactory
);
...
...
src/Compilers/CSharp/Portable/Syntax/SyntaxUtilities.cs
浏览文件 @
c90f3a12
...
...
@@ -70,10 +70,6 @@ internal static bool IsClosureScope(SyntaxNode node)
case
SyntaxKind
.
ForEachStatement
:
case
SyntaxKind
.
UsingStatement
:
// variable captured by a lambda in a let clause,
// e.g. from item in array let a = new Func<int>(() => item)
case
SyntaxKind
.
LetClause
:
// ctor parameter captured by a lambda in a ctor initializer
case
SyntaxKind
.
ConstructorDeclaration
:
return
true
;
...
...
src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.cs
浏览文件 @
c90f3a12
...
...
@@ -497,6 +497,422 @@ void F()
Row
(
21
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
TransparentIdentifiers_FromClause
()
{
var
source0
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
void F()
{
var result = <N:0>from a in new[] { 1 }</N:0>
<N:1>from b in new[] { 1 }</N:1>
<N:2>where <N:7>Z(<N:5>() => a</N:5>) > 0</N:7></N:2>
<N:3>where <N:8>Z(<N:6>() => b</N:7>) > 0</N:8></N:3>
<N:4>select a</N:4>;
}
}"
);
var
source1
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
void F()
{
var result = <N:0>from a in new[] { 1 }</N:0>
<N:1>from b in new[] { 2 }</N:1>
<N:2>where <N:7>Z(<N:5>() => a</N:5>) > 1</N:7></N:2>
<N:3>where <N:8>Z(<N:6>() => b</N:7>) > 2</N:8></N:3>
<N:4>select a</N:4>;
}
}"
);
var
compilation0
=
CreateCompilationWithMscorlib
(
source0
.
Tree
,
new
[]
{
SystemCoreRef
},
options
:
ComSafeDebugDll
.
WithMetadataImportOptions
(
MetadataImportOptions
.
All
));
var
compilation1
=
compilation0
.
WithSource
(
source1
.
Tree
);
var
v0
=
CompileAndVerify
(
compilation0
);
var
md0
=
ModuleMetadata
.
CreateFromImage
(
v0
.
EmittedAssemblyData
);
var
f0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
f1
=
compilation1
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
generation0
=
EmitBaseline
.
CreateInitialBaseline
(
md0
,
v0
.
CreatePdbInfoProvider
().
GetEncMethodDebugInfo
);
var
diff1
=
compilation1
.
EmitDifference
(
generation0
,
ImmutableArray
.
Create
(
new
SemanticEdit
(
SemanticEditKind
.
Update
,
f0
,
f1
,
GetSyntaxMapFromMarkers
(
source0
,
source1
),
preserveLocalVariables
:
true
)));
// no new synthesized members generated (with #1 in names):
diff1
.
VerifySynthesizedMembers
(
"C: {<F>b__1_2, <F>b__1_4, <>c__DisplayClass1_0, <>c__DisplayClass1_1, <>c}"
,
"C.<>c: {<>9__1_0, <>9__1_1, <>9__1_6, <F>b__1_0, <F>b__1_1, <F>b__1_6}"
,
"C.<>c__DisplayClass1_0: {<>h__TransparentIdentifier0, <F>b__3}"
,
"C.<>c__DisplayClass1_1: {<>h__TransparentIdentifier0, <F>b__5}"
,
"<>f__AnonymousType0<<a>j__TPar, <b>j__TPar>: {Equals, GetHashCode, ToString}"
);
var
md1
=
diff1
.
GetMetadata
();
var
reader1
=
md1
.
Reader
;
// Method updates for lambdas:
CheckEncLogDefinitions
(
reader1
,
Row
(
8
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
9
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
11
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
12
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
13
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
8
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
11
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
13
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
15
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
18
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
19
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
20
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
17
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
),
Row
(
18
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
TransparentIdentifiers_LetClause
()
{
var
source0
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
void F()
{
var result = <N:0>from a in new[] { 1 }</N:0>
<N:1>let b = <N:2>Z(<N:3>() => a</N:3>)</N:2></N:1>
<N:4>select <N:5>a + b</N:5></N:4>;
}
}"
);
var
source1
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
void F()
{
var result = <N:0>from a in new[] { 1 }</N:0>
<N:1>let b = <N:2>Z(<N:3>() => a</N:3>) + 1</N:2></N:1>
<N:4>select <N:5>a + b</N:5></N:4>;
}
}"
);
var
compilation0
=
CreateCompilationWithMscorlib
(
source0
.
Tree
,
new
[]
{
SystemCoreRef
},
options
:
ComSafeDebugDll
.
WithMetadataImportOptions
(
MetadataImportOptions
.
All
));
var
compilation1
=
compilation0
.
WithSource
(
source1
.
Tree
);
var
v0
=
CompileAndVerify
(
compilation0
);
var
md0
=
ModuleMetadata
.
CreateFromImage
(
v0
.
EmittedAssemblyData
);
var
f0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
f1
=
compilation1
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
generation0
=
EmitBaseline
.
CreateInitialBaseline
(
md0
,
v0
.
CreatePdbInfoProvider
().
GetEncMethodDebugInfo
);
var
diff1
=
compilation1
.
EmitDifference
(
generation0
,
ImmutableArray
.
Create
(
new
SemanticEdit
(
SemanticEditKind
.
Update
,
f0
,
f1
,
GetSyntaxMapFromMarkers
(
source0
,
source1
),
preserveLocalVariables
:
true
)));
// no new synthesized members generated (with #1 in names):
diff1
.
VerifySynthesizedMembers
(
"C: {<F>b__1_0, <>c__DisplayClass1_0, <>c}"
,
"C.<>c: {<>9__1_2, <F>b__1_2}"
,
"C.<>c__DisplayClass1_0: {a, <F>b__1}"
,
"<>f__AnonymousType0<<a>j__TPar, <b>j__TPar>: {Equals, GetHashCode, ToString}"
);
var
md1
=
diff1
.
GetMetadata
();
var
reader1
=
md1
.
Reader
;
// Method updates for lambdas:
CheckEncLogDefinitions
(
reader1
,
Row
(
6
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
7
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
8
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
8
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
12
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
15
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
15
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
TransparentIdentifiers_JoinClause
()
{
var
source0
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>join b in new[] { 3 } on
<N:3>Z(<N:4>() => <N:5>a + 1</N:5></N:4>)</N:3>
equals
<N:6>Z(<N:7>() => <N:8>b - 1</N:8></N:7>)</N:6></N:2>
<N:9>select <N:10>Z(<N:11>() => <N:12>a + b</N:12></N:11>)</N:10></N:9>;
}
}"
);
var
source1
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>join b in new[] { 3 } on
<N:3>Z(<N:4>() => <N:5>a + 1</N:5></N:4>)</N:3>
equals
<N:6>Z(<N:7>() => <N:8>b - 1</N:8></N:7>)</N:6></N:2>
<N:9>select <N:10>Z(<N:11>() => <N:12>a - b</N:12></N:11>)</N:10></N:9>;
}
}"
);
var
compilation0
=
CreateCompilationWithMscorlib
(
source0
.
Tree
,
new
[]
{
SystemCoreRef
},
options
:
ComSafeDebugDll
.
WithMetadataImportOptions
(
MetadataImportOptions
.
All
));
var
compilation1
=
compilation0
.
WithSource
(
source1
.
Tree
);
var
v0
=
CompileAndVerify
(
compilation0
);
var
md0
=
ModuleMetadata
.
CreateFromImage
(
v0
.
EmittedAssemblyData
);
var
f0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
f1
=
compilation1
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
generation0
=
EmitBaseline
.
CreateInitialBaseline
(
md0
,
v0
.
CreatePdbInfoProvider
().
GetEncMethodDebugInfo
);
var
diff1
=
compilation1
.
EmitDifference
(
generation0
,
ImmutableArray
.
Create
(
new
SemanticEdit
(
SemanticEditKind
.
Update
,
f0
,
f1
,
GetSyntaxMapFromMarkers
(
source0
,
source1
),
preserveLocalVariables
:
true
)));
// no new synthesized members generated (with #1 in names):
diff1
.
VerifySynthesizedMembers
(
"C.<>c__DisplayClass1_0: {a, <F>b__1}"
,
"C.<>c__DisplayClass1_1: {b, <F>b__3}"
,
"C.<>c__DisplayClass1_2: {a, b, <F>b__5}"
,
"C: {<F>b__1_0, <F>b__1_2, <F>b__1_4, <>c__DisplayClass1_0, <>c__DisplayClass1_1, <>c__DisplayClass1_2}"
);
var
md1
=
diff1
.
GetMetadata
();
var
reader1
=
md1
.
Reader
;
// Method updates for lambdas:
CheckEncLogDefinitions
(
reader1
,
Row
(
6
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
7
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
8
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
9
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
2
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
4
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
5
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
6
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
8
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
12
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
),
Row
(
11
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
),
Row
(
12
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
TransparentIdentifiers_JoinIntoClause
()
{
var
source0
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>join b in new[] { 3 } on
<N:3>a + 1</N:3> equals <N:4>b - 1</N:4>
into g</N:2>
<N:5>select <N:6>Z(<N:7>() => <N:8>g.First()</N:8></N:7>)</N:6></N:5>;
}
}"
);
var
source1
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>join b in new[] { 3 } on
<N:3>a + 1</N:3> equals <N:4>b - 1</N:4>
into g</N:2>
<N:5>select <N:6>Z(<N:7>() => <N:8>g.Last()</N:8></N:7>)</N:6></N:5>;
}
}"
);
var
compilation0
=
CreateCompilationWithMscorlib
(
source0
.
Tree
,
new
[]
{
SystemCoreRef
},
options
:
ComSafeDebugDll
.
WithMetadataImportOptions
(
MetadataImportOptions
.
All
));
var
compilation1
=
compilation0
.
WithSource
(
source1
.
Tree
);
var
v0
=
CompileAndVerify
(
compilation0
);
var
md0
=
ModuleMetadata
.
CreateFromImage
(
v0
.
EmittedAssemblyData
);
var
f0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
f1
=
compilation1
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
generation0
=
EmitBaseline
.
CreateInitialBaseline
(
md0
,
v0
.
CreatePdbInfoProvider
().
GetEncMethodDebugInfo
);
var
diff1
=
compilation1
.
EmitDifference
(
generation0
,
ImmutableArray
.
Create
(
new
SemanticEdit
(
SemanticEditKind
.
Update
,
f0
,
f1
,
GetSyntaxMapFromMarkers
(
source0
,
source1
),
preserveLocalVariables
:
true
)));
// no new synthesized members generated (with #1 in names):
diff1
.
VerifySynthesizedMembers
(
"C: {<F>b__1_2, <>c__DisplayClass1_0, <>c}"
,
"C.<>c: {<>9__1_0, <>9__1_1, <F>b__1_0, <F>b__1_1}"
,
"C.<>c__DisplayClass1_0: {g, <F>b__3}"
);
var
md1
=
diff1
.
GetMetadata
();
var
reader1
=
md1
.
Reader
;
// Method updates for lambdas:
CheckEncLogDefinitions
(
reader1
,
Row
(
4
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
5
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
6
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
2
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
4
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
6
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
9
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
10
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
7
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
TransparentIdentifiers_QueryContinuation
()
{
var
source0
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>group a by <N:3>a + 1</N:3></N:2>
<N:4>into g
<N:5>select <N:6>Z(<N:7>() => <N:8>g.First()</N:8></N:7>)</N:6></N:5></N:4>;
}
}"
);
var
source1
=
MarkedSource
(
@"
using System;
using System.Linq;
class C
{
int Z(Func<int> f)
{
return 1;
}
public void F()
{
var result = <N:0>from a in <N:1>new[] { 1 }</N:1></N:0>
<N:2>group a by <N:3>a + 1</N:3></N:2>
<N:4>into g
<N:5>select <N:6>Z(<N:7>() => <N:8>g.Last()</N:8></N:7>)</N:6></N:5></N:4>;
}
}"
);
var
compilation0
=
CreateCompilationWithMscorlib
(
source0
.
Tree
,
new
[]
{
SystemCoreRef
},
options
:
ComSafeDebugDll
.
WithMetadataImportOptions
(
MetadataImportOptions
.
All
));
var
compilation1
=
compilation0
.
WithSource
(
source1
.
Tree
);
var
v0
=
CompileAndVerify
(
compilation0
);
var
md0
=
ModuleMetadata
.
CreateFromImage
(
v0
.
EmittedAssemblyData
);
var
f0
=
compilation0
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
f1
=
compilation1
.
GetMember
<
MethodSymbol
>(
"C.F"
);
var
generation0
=
EmitBaseline
.
CreateInitialBaseline
(
md0
,
v0
.
CreatePdbInfoProvider
().
GetEncMethodDebugInfo
);
var
diff1
=
compilation1
.
EmitDifference
(
generation0
,
ImmutableArray
.
Create
(
new
SemanticEdit
(
SemanticEditKind
.
Update
,
f0
,
f1
,
GetSyntaxMapFromMarkers
(
source0
,
source1
),
preserveLocalVariables
:
true
)));
// no new synthesized members generated (with #1 in names):
diff1
.
VerifySynthesizedMembers
(
"C: {<F>b__1_1, <>c__DisplayClass1_0, <>c}"
,
"C.<>c: {<>9__1_0, <F>b__1_0}"
,
"C.<>c__DisplayClass1_0: {g, <F>b__2}"
);
var
md1
=
diff1
.
GetMetadata
();
var
reader1
=
md1
.
Reader
;
// Method updates for lambdas:
CheckEncLogDefinitions
(
reader1
,
Row
(
4
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
5
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
6
,
TableIndex
.
StandAloneSig
,
EditAndContinueOperation
.
Default
),
Row
(
2
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
4
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
6
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
9
,
TableIndex
.
MethodDef
,
EditAndContinueOperation
.
Default
),
Row
(
7
,
TableIndex
.
CustomAttribute
,
EditAndContinueOperation
.
Default
));
}
[
Fact
]
public
void
UniqueSynthesizedNames1
()
{
...
...
src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
浏览文件 @
c90f3a12
...
...
@@ -6215,7 +6215,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select b.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select b.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6224,7 +6224,7 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
s = from a in b select b.bar
"
,
"where clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
from
"
,
"where clause"
));
}
[
Fact
]
...
...
@@ -6244,7 +6244,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select a.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select a.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6253,7 +6253,7 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
s = from a in b select a.bar
"
,
"let clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
from
"
,
"let clause"
));
}
[
Fact
]
...
...
@@ -6276,7 +6276,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select a.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select a.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6285,7 +6285,7 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
s = from a in b select a.bar
"
,
"join clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
from
"
,
"join clause"
));
}
[
Fact
]
...
...
@@ -6308,7 +6308,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select a.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select a.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6317,7 +6317,7 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
s = from a in b select a.bar
"
,
"orderby clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
from
"
,
"orderby clause"
));
}
[
Fact
]
...
...
@@ -6340,7 +6340,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select a.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select a.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6349,7 +6349,7 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
s = from a in b select a.bar
"
,
"orderby clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"
from
"
,
"orderby clause"
));
}
[
Fact
]
...
...
@@ -6372,7 +6372,7 @@ class C
{
static void Main(string[] args)
{
var
<AS:0>s = from a in b select a.bar</AS:0>
;
var
s = <AS:0>from</AS:0> a in b select a.bar
;
<AS:1>s.ToArray();</AS:1>
}
}
...
...
@@ -6381,7 +6381,100 @@ static void Main(string[] args)
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"s = from a in b select a.bar"
,
"orderby clause"
));
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"from"
,
"orderby clause"
));
}
[
Fact
]
public
void
Queries_Remove_JoinInto1
()
{
string
src1
=
@"
class C
{
static void Main()
{
var q = from x in xs
join y in ys on F() equals G() into g
select <AS:0>1</AS:0>;
}
}"
;
string
src2
=
@"
class C
{
static void Main()
{
var q = from x in xs
join y in ys on F() equals G()
select <AS:0>1</AS:0>;
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
);
}
[
Fact
]
public
void
Queries_Remove_QueryContinuation1
()
{
string
src1
=
@"
class C
{
static void Main()
{
var q = from x in xs
group x by x.F() into g
where <AS:0>g.F()</AS:0>
select 1;
}
}"
;
string
src2
=
@"
class C
{
static void Main()
{
var q = from x in xs
group x by x.F() <AS:0>into</AS:0> g
select 1;
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"into"
,
"where clause"
));
}
[
Fact
]
public
void
Queries_Remove_QueryContinuation2
()
{
string
src1
=
@"
class C
{
static void Main()
{
var q = from x in xs
group x by x.F() into g
select <AS:0>1</AS:0>;
}
}"
;
string
src2
=
@"
class C
{
static void Main()
{
var q = from x in xs
<AS:0>join</AS:0> y in ys on F() equals G() into g
select 1;
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
,
Diagnostic
(
RudeEditKind
.
ActiveStatementLambdaRemoved
,
"join"
,
"select clause"
));
}
#
endregion
...
...
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
浏览文件 @
c90f3a12
此差异已折叠。
点击以展开。
src/EditorFeatures/Test/EditAndContinue/Extensions.cs
浏览文件 @
c90f3a12
...
...
@@ -13,7 +13,7 @@ internal static class Extensions
public
static
void
Verify
(
this
IEnumerable
<
RudeEditDiagnostic
>
diagnostics
,
string
newSource
,
params
RudeEditDiagnosticDescription
[]
expectedDiagnostics
)
{
var
actualDiagnostics
=
diagnostics
.
ToDescription
(
newSource
,
expectedDiagnostics
.
Any
(
d
=>
d
.
FirstLine
!=
null
)).
ToArray
();
AssertEx
.
Equal
(
expectedDiagnostics
,
actualDiagnostics
,
itemSeparator
:
",\r\n"
);
AssertEx
.
Set
Equal
(
expectedDiagnostics
,
actualDiagnostics
,
itemSeparator
:
",\r\n"
);
}
private
static
IEnumerable
<
RudeEditDiagnosticDescription
>
ToDescription
(
this
IEnumerable
<
RudeEditDiagnostic
>
diagnostics
,
string
newSource
,
bool
includeFirstLines
)
...
...
src/Features/CSharp/CSharpFeatures.csproj
浏览文件 @
c90f3a12
...
...
@@ -372,8 +372,8 @@
<ItemGroup>
<EmbeddedResource
Include=
"CSharpFeaturesResources.resx"
>
<Generator>
ResXFileCodeGenerator
</Generator>
<LastGenOutput>
CSharpFeaturesResources.Designer.cs
</LastGenOutput>
<SubType>
Designer
</SubType>
<LastGenOutput>
CSharpFeaturesResources.Designer.cs
</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
...
...
@@ -386,4 +386,4 @@
<Import
Project=
"..\..\..\build\VSL.Imports.Closed.targets"
/>
<Import
Project=
"$(SolutionDir)\.nuget\NuGet.targets"
Condition=
"Exists('$(SolutionDir)\.nuget\NuGet.targets')"
/>
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
src/Features/CSharp/CSharpFeaturesResources.Designer.cs
浏览文件 @
c90f3a12
...
...
@@ -60,6 +60,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to anonymous method.
/// </summary>
internal
static
string
AnonymousMethod
{
get
{
return
ResourceManager
.
GetString
(
"AnonymousMethod"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Autoselect disabled due to possible explicitly named anonymous type member creation..
/// </summary>
...
...
@@ -123,6 +132,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to await expression.
/// </summary>
internal
static
string
AwaitExpression
{
get
{
return
ResourceManager
.
GetString
(
"AwaitExpression"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to can't determine valid range of statements to extract out.
/// </summary>
...
...
@@ -141,6 +159,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to catch clause.
/// </summary>
internal
static
string
CatchClause
{
get
{
return
ResourceManager
.
GetString
(
"CatchClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Change return type from {0} to {1}.
/// </summary>
...
...
@@ -159,6 +186,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to checked statement.
/// </summary>
internal
static
string
CheckedStatement
{
get
{
return
ResourceManager
.
GetString
(
"CheckedStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Conflict(s) detected..
/// </summary>
...
...
@@ -213,6 +249,42 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to filter clause.
/// </summary>
internal
static
string
FilterClause
{
get
{
return
ResourceManager
.
GetString
(
"FilterClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to finally clause.
/// </summary>
internal
static
string
FinallyClause
{
get
{
return
ResourceManager
.
GetString
(
"FinallyClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to fixed statement.
/// </summary>
internal
static
string
FixedStatement
{
get
{
return
ResourceManager
.
GetString
(
"FixedStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to foreach statement.
/// </summary>
internal
static
string
ForEachStatement
{
get
{
return
ResourceManager
.
GetString
(
"ForEachStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to TODO: free unmanaged resources (unmanaged objects) and override a finalizer below..
/// </summary>
...
...
@@ -222,6 +294,24 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to from clause.
/// </summary>
internal
static
string
FromClause
{
get
{
return
ResourceManager
.
GetString
(
"FromClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to groupby clause.
/// </summary>
internal
static
string
GroupByClause
{
get
{
return
ResourceManager
.
GetString
(
"GroupByClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Implement Abstract Class.
/// </summary>
...
...
@@ -267,6 +357,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to into clause.
/// </summary>
internal
static
string
IntoClause
{
get
{
return
ResourceManager
.
GetString
(
"IntoClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid selection..
/// </summary>
...
...
@@ -285,6 +384,24 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to join clause.
/// </summary>
internal
static
string
JoinClause
{
get
{
return
ResourceManager
.
GetString
(
"JoinClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to lambda.
/// </summary>
internal
static
string
Lambda
{
get
{
return
ResourceManager
.
GetString
(
"Lambda"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to <lambda expression>.
/// </summary>
...
...
@@ -294,6 +411,24 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to let clause.
/// </summary>
internal
static
string
LetClause
{
get
{
return
ResourceManager
.
GetString
(
"LetClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to lock statement.
/// </summary>
internal
static
string
LockStatement
{
get
{
return
ResourceManager
.
GetString
(
"LockStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Make the containing scope 'async'..
/// </summary>
...
...
@@ -366,6 +501,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to orderby clause.
/// </summary>
internal
static
string
OrderByClause
{
get
{
return
ResourceManager
.
GetString
(
"OrderByClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Organize Usings.
/// </summary>
...
...
@@ -393,6 +537,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to query body.
/// </summary>
internal
static
string
QueryBody
{
get
{
return
ResourceManager
.
GetString
(
"QueryBody"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to <range variable>.
/// </summary>
...
...
@@ -447,6 +600,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to select clause.
/// </summary>
internal
static
string
SelectClause
{
get
{
return
ResourceManager
.
GetString
(
"SelectClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Selection can not be part of constant initializer expression..
/// </summary>
...
...
@@ -591,6 +753,24 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to try block.
/// </summary>
internal
static
string
TryBlock
{
get
{
return
ResourceManager
.
GetString
(
"TryBlock"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to unchecked statement.
/// </summary>
internal
static
string
UncheckedStatement
{
get
{
return
ResourceManager
.
GetString
(
"UncheckedStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to TODO: uncomment the following line if the finalizer is overridden above..
/// </summary>
...
...
@@ -600,6 +780,15 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to using statement.
/// </summary>
internal
static
string
UsingStatement
{
get
{
return
ResourceManager
.
GetString
(
"UsingStatement"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to Warning: Declaration changes scope and may change meaning..
/// </summary>
...
...
@@ -608,5 +797,23 @@ internal class CSharpFeaturesResources {
return
ResourceManager
.
GetString
(
"WarningDeclarationChangesScope"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to where clause.
/// </summary>
internal
static
string
WhereClause
{
get
{
return
ResourceManager
.
GetString
(
"WhereClause"
,
resourceCulture
);
}
}
/// <summary>
/// Looks up a localized string similar to yield statement.
/// </summary>
internal
static
string
YieldStatement
{
get
{
return
ResourceManager
.
GetString
(
"YieldStatement"
,
resourceCulture
);
}
}
}
}
src/Features/CSharp/CSharpFeaturesResources.resx
浏览文件 @
c90f3a12
...
...
@@ -300,4 +300,73 @@
<data
name=
"UncommentTheFollowingIfFinalizerOverriddenTodo"
xml:space=
"preserve"
>
<value>
TODO: uncomment the following line if the finalizer is overridden above.
</value>
</data>
<data
name=
"TryBlock"
xml:space=
"preserve"
>
<value>
try block
</value>
</data>
<data
name=
"CatchClause"
xml:space=
"preserve"
>
<value>
catch clause
</value>
</data>
<data
name=
"FilterClause"
xml:space=
"preserve"
>
<value>
filter clause
</value>
</data>
<data
name=
"FinallyClause"
xml:space=
"preserve"
>
<value>
finally clause
</value>
</data>
<data
name=
"FixedStatement"
xml:space=
"preserve"
>
<value>
fixed statement
</value>
</data>
<data
name=
"UsingStatement"
xml:space=
"preserve"
>
<value>
using statement
</value>
</data>
<data
name=
"LockStatement"
xml:space=
"preserve"
>
<value>
lock statement
</value>
</data>
<data
name=
"ForEachStatement"
xml:space=
"preserve"
>
<value>
foreach statement
</value>
</data>
<data
name=
"CheckedStatement"
xml:space=
"preserve"
>
<value>
checked statement
</value>
</data>
<data
name=
"UncheckedStatement"
xml:space=
"preserve"
>
<value>
unchecked statement
</value>
</data>
<data
name=
"YieldStatement"
xml:space=
"preserve"
>
<value>
yield statement
</value>
</data>
<data
name=
"AwaitExpression"
xml:space=
"preserve"
>
<value>
await expression
</value>
</data>
<data
name=
"Lambda"
xml:space=
"preserve"
>
<value>
lambda
</value>
</data>
<data
name=
"AnonymousMethod"
xml:space=
"preserve"
>
<value>
anonymous method
</value>
</data>
<data
name=
"FromClause"
xml:space=
"preserve"
>
<value>
from clause
</value>
</data>
<data
name=
"JoinClause"
xml:space=
"preserve"
>
<value>
join clause
</value>
</data>
<data
name=
"LetClause"
xml:space=
"preserve"
>
<value>
let clause
</value>
</data>
<data
name=
"WhereClause"
xml:space=
"preserve"
>
<value>
where clause
</value>
</data>
<data
name=
"OrderByClause"
xml:space=
"preserve"
>
<value>
orderby clause
</value>
</data>
<data
name=
"SelectClause"
xml:space=
"preserve"
>
<value>
select clause
</value>
</data>
<data
name=
"GroupByClause"
xml:space=
"preserve"
>
<value>
groupby clause
</value>
</data>
<data
name=
"QueryBody"
xml:space=
"preserve"
>
<value>
query body
</value>
</data>
<data
name=
"IntoClause"
xml:space=
"preserve"
>
<value>
into clause
</value>
</data>
</root>
\ No newline at end of file
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
浏览文件 @
c90f3a12
...
...
@@ -1145,18 +1145,31 @@ internal static TextSpan GetDiagnosticSpanImpl(SyntaxKind kind, SyntaxNode node,
case
SyntaxKind
.
QueryExpression
:
return
((
QueryExpressionSyntax
)
node
).
FromClause
.
FromKeyword
.
Span
;
case
SyntaxKind
.
QueryBody
:
var
queryBody
=
(
QueryBodySyntax
)
node
;
return
GetDiagnosticSpanImpl
(
queryBody
.
Clauses
.
FirstOrDefault
()
??
queryBody
.
Parent
,
editKind
);
case
SyntaxKind
.
QueryContinuation
:
return
((
QueryContinuationSyntax
)
node
).
IntoKeyword
.
Span
;
case
SyntaxKind
.
FromClause
:
return
((
FromClauseSyntax
)
node
).
FromKeyword
.
Span
;
case
SyntaxKind
.
JoinClause
:
return
((
JoinClauseSyntax
)
node
).
JoinKeyword
.
Span
;
case
SyntaxKind
.
JoinIntoClause
:
return
((
JoinIntoClauseSyntax
)
node
).
IntoKeyword
.
Span
;
case
SyntaxKind
.
LetClause
:
return
((
LetClauseSyntax
)
node
).
LetKeyword
.
Span
;
case
SyntaxKind
.
WhereClause
:
return
((
WhereClauseSyntax
)
node
).
WhereKeyword
.
Span
;
case
SyntaxKind
.
OrderByClause
:
return
((
OrderByClauseSyntax
)
node
).
OrderByKeyword
.
Span
;
case
SyntaxKind
.
AscendingOrdering
:
case
SyntaxKind
.
DescendingOrdering
:
return
node
.
Span
;
...
...
@@ -1168,7 +1181,7 @@ internal static TextSpan GetDiagnosticSpanImpl(SyntaxKind kind, SyntaxNode node,
return
((
GroupClauseSyntax
)
node
).
GroupKeyword
.
Span
;
default
:
throw
ExceptionUtilities
.
Un
reachable
;
throw
ExceptionUtilities
.
Un
expectedValue
(
kind
)
;
}
}
...
...
@@ -1316,73 +1329,81 @@ internal static string GetStatementDisplayNameImpl(SyntaxNode node)
switch
(
node
.
Kind
())
{
case
SyntaxKind
.
TryStatement
:
return
"try block"
;
return
CSharpFeaturesResources
.
TryBlock
;
case
SyntaxKind
.
CatchClause
:
return
"catch clause"
;
return
CSharpFeaturesResources
.
CatchClause
;
case
SyntaxKind
.
CatchFilterClause
:
return
"filter clause"
;
return
CSharpFeaturesResources
.
FilterClause
;
case
SyntaxKind
.
FinallyClause
:
return
"finally clause"
;
return
CSharpFeaturesResources
.
FinallyClause
;
case
SyntaxKind
.
FixedStatement
:
return
"fixed statement"
;
return
CSharpFeaturesResources
.
FixedStatement
;
case
SyntaxKind
.
UsingStatement
:
return
"using statement"
;
return
CSharpFeaturesResources
.
UsingStatement
;
case
SyntaxKind
.
LockStatement
:
return
"lock statement"
;
return
CSharpFeaturesResources
.
LockStatement
;
case
SyntaxKind
.
ForEachStatement
:
return
"foreach statement"
;
return
CSharpFeaturesResources
.
ForEachStatement
;
case
SyntaxKind
.
CheckedStatement
:
return
"checked statement"
;
return
CSharpFeaturesResources
.
CheckedStatement
;
case
SyntaxKind
.
UncheckedStatement
:
return
"unchecked statement"
;
return
CSharpFeaturesResources
.
UncheckedStatement
;
case
SyntaxKind
.
YieldBreakStatement
:
case
SyntaxKind
.
YieldReturnStatement
:
return
"yield statement"
;
return
CSharpFeaturesResources
.
YieldStatement
;
case
SyntaxKind
.
AwaitExpression
:
return
"await expression"
;
return
CSharpFeaturesResources
.
AwaitExpression
;
case
SyntaxKind
.
ParenthesizedLambdaExpression
:
case
SyntaxKind
.
SimpleLambdaExpression
:
return
"lambda"
;
return
CSharpFeaturesResources
.
Lambda
;
case
SyntaxKind
.
AnonymousMethodExpression
:
return
"anonymous method"
;
return
CSharpFeaturesResources
.
AnonymousMethod
;
case
SyntaxKind
.
FromClause
:
return
"from clause"
;
return
CSharpFeaturesResources
.
FromClause
;
case
SyntaxKind
.
JoinClause
:
return
"join clause"
;
case
SyntaxKind
.
JoinIntoClause
:
return
CSharpFeaturesResources
.
JoinClause
;
case
SyntaxKind
.
LetClause
:
return
"let clause"
;
return
CSharpFeaturesResources
.
LetClause
;
case
SyntaxKind
.
WhereClause
:
return
"where clause"
;
return
CSharpFeaturesResources
.
WhereClause
;
case
SyntaxKind
.
OrderByClause
:
case
SyntaxKind
.
AscendingOrdering
:
case
SyntaxKind
.
DescendingOrdering
:
return
"orderby clause"
;
return
CSharpFeaturesResources
.
OrderByClause
;
case
SyntaxKind
.
SelectClause
:
return
"select clause"
;
return
CSharpFeaturesResources
.
SelectClause
;
case
SyntaxKind
.
GroupClause
:
return
"groupby clause"
;
return
CSharpFeaturesResources
.
GroupByClause
;
case
SyntaxKind
.
QueryBody
:
return
CSharpFeaturesResources
.
QueryBody
;
case
SyntaxKind
.
QueryContinuation
:
return
CSharpFeaturesResources
.
IntoClause
;
default
:
throw
ExceptionUtilities
.
Un
reachable
;
throw
ExceptionUtilities
.
Un
expectedValue
(
node
.
Kind
())
;
}
}
...
...
src/Features/CSharp/EditAndContinue/StatementSyntaxComparer.cs
浏览文件 @
c90f3a12
...
...
@@ -51,28 +51,29 @@ protected internal override IEnumerable<SyntaxNode> GetChildren(SyntaxNode node)
return
EnumerateRootChildren
(
node
);
}
return
NonRootHasChildren
(
node
)
?
EnumerateChildren
(
node
)
:
null
;
return
IsLeaf
(
node
)
?
null
:
EnumerateNonRootChildren
(
node
)
;
}
private
IEnumerable
<
SyntaxNode
>
EnumerateChildren
(
SyntaxNode
node
)
private
IEnumerable
<
SyntaxNode
>
Enumerate
NonRoot
Children
(
SyntaxNode
node
)
{
foreach
(
var
child
in
node
.
ChildNodes
AndTokens
())
foreach
(
var
child
in
node
.
ChildNodes
())
{
var
childNode
=
child
.
AsNode
();
if
(
childNode
!=
null
)
if
(
SyntaxFacts
.
IsLambdaBody
(
child
))
{
if
(
GetLabel
(
childNode
)
!=
IgnoredNode
)
{
yield
return
childNode
;
}
else
continue
;
}
if
(
GetLabelImpl
(
child
)
!=
Label
.
Ignored
)
{
yield
return
child
;
}
else
{
foreach
(
var
descendant
in
child
.
DescendantNodes
(
descendIntoChildren
:
DescendIntoChildren
))
{
foreach
(
var
descendant
in
childNode
.
DescendantNodes
(
descendIntoChildren
:
SyntaxUtilities
.
IsNotLambda
))
if
(
HasLabel
(
descendant
))
{
if
(
EnumerateExpressionDescendant
(
descendant
))
{
yield
return
descendant
;
}
yield
return
descendant
;
}
}
}
...
...
@@ -81,17 +82,17 @@ private IEnumerable<SyntaxNode> EnumerateChildren(SyntaxNode node)
private
IEnumerable
<
SyntaxNode
>
EnumerateRootChildren
(
SyntaxNode
root
)
{
var
child
Node
=
(
root
==
_oldRoot
)
?
_oldRootChild
:
_newRootChild
;
var
child
=
(
root
==
_oldRoot
)
?
_oldRootChild
:
_newRootChild
;
if
(
GetLabel
(
childNode
)
!=
IgnoredNode
)
if
(
GetLabel
Impl
(
child
)
!=
Label
.
Ignored
)
{
yield
return
child
Node
;
yield
return
child
;
}
else
{
foreach
(
var
descendant
in
child
Node
.
DescendantNodes
(
descendIntoChildren
:
SyntaxUtilities
.
IsNotLambda
))
foreach
(
var
descendant
in
child
.
DescendantNodes
(
descendIntoChildren
:
DescendIntoChildren
))
{
if
(
EnumerateExpressionDescendant
(
descendant
))
if
(
HasLabel
(
descendant
))
{
yield
return
descendant
;
}
...
...
@@ -99,46 +100,39 @@ private IEnumerable<SyntaxNode> EnumerateRootChildren(SyntaxNode root)
}
}
private
static
bool
EnumerateExpressionDescendant
(
SyntaxNode
node
)
private
bool
DescendIntoChildren
(
SyntaxNode
node
)
{
return
node
.
IsKind
(
SyntaxKind
.
VariableDeclarator
)
||
node
.
IsKind
(
SyntaxKind
.
AwaitExpression
)
||
SyntaxUtilities
.
IsLambda
(
node
);
return
!
SyntaxFacts
.
IsLambdaBody
(
node
)
&&
!
HasLabel
(
node
);
}
protected
internal
sealed
override
IEnumerable
<
SyntaxNode
>
GetDescendants
(
SyntaxNode
node
)
{
if
(
node
==
_oldRoot
||
node
==
_newRoot
)
{
var
descendant
Node
=
(
node
==
_oldRoot
)
?
_oldRootChild
:
_newRootChild
;
var
descendant
=
(
node
==
_oldRoot
)
?
_oldRootChild
:
_newRootChild
;
if
(
GetLabel
(
descendantNode
)
!=
IgnoredNode
)
if
(
GetLabel
Impl
(
descendant
)
!=
Label
.
Ignored
)
{
yield
return
descendant
Node
;
yield
return
descendant
;
}
node
=
descendant
Node
;
node
=
descendant
;
}
foreach
(
var
descendant
in
node
.
DescendantNodes
(
descendIntoChildren
:
NonRootHasChildren
,
descendIntoTrivia
:
false
))
foreach
(
var
descendant
in
node
.
DescendantNodes
(
descendIntoChildren
:
c
=>
c
==
node
||
!
IsLeaf
(
c
)
&&
!
SyntaxFacts
.
IsLambdaBody
(
c
)))
{
if
(
GetLabel
(
descendant
)
!=
IgnoredNode
)
if
(
!
SyntaxFacts
.
IsLambdaBody
(
descendant
)
&&
HasLabel
(
descendant
)
)
{
yield
return
descendant
;
}
}
}
private
static
bool
NonRootHasChildren
(
SyntaxNode
node
)
private
static
bool
IsLeaf
(
SyntaxNode
node
)
{
// Leaves are labeled statements that don't have a labeled child.
// A non-labeled statement may not be leave since it may contain a lambda.
bool
isLeaf
;
Classify
(
node
.
Kind
(),
node
,
out
isLeaf
);
return
!
isLeaf
;
return
isLeaf
;
}
#
endregion
...
...
@@ -194,13 +188,18 @@ internal enum Label
AwaitExpression
,
Lambda
,
FromClauseLambda
,
LetClauseLambda
,
WhereClauseLambda
,
OrderingLambda
,
SelectClauseLambda
,
JoinClauseLambda
,
GroupClauseLambda
,
FromClause
,
QueryBody
,
FromClauseLambda
,
// tied to parent
LetClauseLambda
,
// tied to parent
WhereClauseLambda
,
// tied to parent
OrderByClause
,
// tied to parent
OrderingLambda
,
// tied to parent
SelectClauseLambda
,
// tied to parent
JoinClauseLambda
,
// tied to parent
JoinIntoClause
,
// tied to parent
GroupClauseLambda
,
// tied to parent
QueryContinuation
,
// tied to parent
// helpers:
Count
,
...
...
@@ -222,6 +221,16 @@ private static int TiedToAncestor(Label label)
case
Label
.
FinallyClause
:
case
Label
.
ForStatementPart
:
case
Label
.
YieldStatement
:
case
Label
.
FromClauseLambda
:
case
Label
.
LetClauseLambda
:
case
Label
.
WhereClauseLambda
:
case
Label
.
OrderByClause
:
case
Label
.
OrderingLambda
:
case
Label
.
SelectClauseLambda
:
case
Label
.
JoinClauseLambda
:
case
Label
.
JoinIntoClause
:
case
Label
.
GroupClauseLambda
:
case
Label
.
QueryContinuation
:
return
1
;
default
:
...
...
@@ -360,14 +369,16 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL
case
SyntaxKind
.
ParenthesizedLambdaExpression
:
case
SyntaxKind
.
SimpleLambdaExpression
:
case
SyntaxKind
.
AnonymousMethodExpression
:
isLeaf
=
true
;
return
Label
.
Lambda
;
case
SyntaxKind
.
FromClause
:
// The first from clause of a query is not a lambda.
// We have to assign it a label different from "FromClauseLambda"
// so that we won't match lambda-from to non-lambda-from.
// Since such from clause is just another expression the label should be "Ignored".
//
// Since FromClause declares range variables we need to include it in the map,
// so that we are able to map range variable declarations.
// Therefore we assign it a dedicated label.
//
// The parent is not available only when comparing nodes for value equality.
// In that case we use "Ignored" for all from clauses, even when they translate to lambdas.
...
...
@@ -375,36 +386,40 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL
// in the from clause lambda, which is ok.
if
(
nodeOpt
==
null
||
nodeOpt
.
Parent
.
IsKind
(
SyntaxKind
.
QueryExpression
))
{
// may contain lambda, so it's not a leaf node
return
Label
.
Ignored
;
return
Label
.
FromClause
;
}
isLeaf
=
true
;
return
Label
.
FromClauseLambda
;
case
SyntaxKind
.
QueryBody
:
return
Label
.
QueryBody
;
case
SyntaxKind
.
QueryContinuation
:
return
Label
.
QueryContinuation
;
case
SyntaxKind
.
LetClause
:
isLeaf
=
true
;
return
Label
.
LetClauseLambda
;
case
SyntaxKind
.
WhereClause
:
isLeaf
=
true
;
return
Label
.
WhereClauseLambda
;
case
SyntaxKind
.
OrderByClause
:
return
Label
.
OrderByClause
;
case
SyntaxKind
.
AscendingOrdering
:
case
SyntaxKind
.
DescendingOrdering
:
isLeaf
=
true
;
return
Label
.
OrderingLambda
;
case
SyntaxKind
.
SelectClause
:
isLeaf
=
true
;
return
Label
.
SelectClauseLambda
;
case
SyntaxKind
.
JoinClause
:
isLeaf
=
true
;
return
Label
.
JoinClauseLambda
;
case
SyntaxKind
.
JoinIntoClause
:
return
Label
.
JoinIntoClause
;
case
SyntaxKind
.
GroupClause
:
isLeaf
=
true
;
return
Label
.
GroupClauseLambda
;
case
SyntaxKind
.
IdentifierName
:
...
...
@@ -420,7 +435,6 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL
case
SyntaxKind
.
OmittedTypeArgument
:
case
SyntaxKind
.
NameColon
:
case
SyntaxKind
.
StackAllocArrayCreationExpression
:
case
SyntaxKind
.
JoinIntoClause
:
case
SyntaxKind
.
OmittedArraySizeExpression
:
case
SyntaxKind
.
ThisExpression
:
case
SyntaxKind
.
BaseExpression
:
...
...
@@ -434,7 +448,7 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL
case
SyntaxKind
.
TypeOfExpression
:
case
SyntaxKind
.
SizeOfExpression
:
case
SyntaxKind
.
DefaultExpression
:
// can't contain a lambda:
// can't contain a lambda
/await/anonymous type
:
isLeaf
=
true
;
return
Label
.
Ignored
;
...
...
@@ -506,18 +520,16 @@ public override bool ValuesEqual(SyntaxNode left, SyntaxNode right)
return
true
;
default
:
// When a value of a statement containing lambdas, and await expressions, e.g.
// F(x => x, G(y => y), from x in y select x, await a);
// is compared we descend into expressions and include them in the value comparison (they are not labeled)
// but not into the contained lambda and await expression nodes (because they are labeled).
//
if
(
NonRootHasChildren
(
left
))
// When comparing the value of a node with its partner we are deciding whether to add an Update edit for the pair.
// If the actual change is under a descendant labeled node we don't want to attribute it to the node being compared,
// so we skip all labeled children when recursively checking for equivalence.
if
(
IsLeaf
(
left
))
{
ignoreChildNode
=
IgnoreLabeledChild
;
ignoreChildNode
=
null
;
}
else
{
ignoreChildNode
=
null
;
ignoreChildNode
=
IgnoreLabeledChild
;
}
break
;
...
...
src/Features/CSharp/EditAndContinue/SyntaxUtilities.cs
浏览文件 @
c90f3a12
...
...
@@ -186,6 +186,21 @@ public static bool IsLambda(SyntaxNode node)
return
false
;
}
public
static
bool
IsRangeVariableDeclarator
(
SyntaxNode
node
)
{
switch
(
node
.
Kind
())
{
case
SyntaxKind
.
FromClause
:
case
SyntaxKind
.
JoinClause
:
case
SyntaxKind
.
LetClause
:
case
SyntaxKind
.
JoinIntoClause
:
case
SyntaxKind
.
QueryContinuation
:
return
true
;
}
return
false
;
}
public
static
bool
TryGetLambdaBodies
(
SyntaxNode
node
,
out
SyntaxNode
body1
,
out
SyntaxNode
body2
)
{
body1
=
null
;
...
...
@@ -200,15 +215,13 @@ public static bool TryGetLambdaBodies(SyntaxNode node, out SyntaxNode body1, out
return
true
;
case
SyntaxKind
.
FromClause
:
var
fromClause
=
(
FromClauseSyntax
)
node
;
// The first from clause of a query expression is not a lambda.
if
(
fromClaus
e
.
Parent
.
IsKind
(
SyntaxKind
.
QueryExpression
))
if
(
nod
e
.
Parent
.
IsKind
(
SyntaxKind
.
QueryExpression
))
{
return
false
;
}
body1
=
fromClause
.
Expression
;
body1
=
((
FromClauseSyntax
)
node
)
.
Expression
;
return
true
;
case
SyntaxKind
.
JoinClause
:
...
...
src/Features/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
浏览文件 @
c90f3a12
...
...
@@ -2985,26 +2985,41 @@ private SyntaxNode GetVariableSyntax(ISymbol localOrParameter, CancellationToken
ISymbol
oldCapture
=
oldCaptures
[
oldCaptureIndex
];
// Parameter capture can't be changed to local capture and vice versa
// because parameters can't be introduced or deleted during EnC
// (we checked above for changes in lambda signatures).
// Also range variables can't be mapped to other variables since htey have
// different kinds of delcarator syntax nodes.
Debug
.
Assert
(
oldCapture
.
Kind
==
newCapture
.
Kind
);
// Range variables don't have types. Each transparent identifier (range variable use)
// might have a different type. Changing these types is ok as long as the containing lambda
// signatures remain unchanged, which we validate for all lambdas in general.
//
// The scope of a transparent identifier is the containing lambda body. Since we verify that
// each lambda body accesses the same captured variables (including range variables)
// the corresponding scopes are guaranteed to be preserved as well.
if
(
oldCapture
.
Kind
==
SymbolKind
.
RangeVariable
)
{
continue
;
}
// type check
var
oldType
=
GetType
(
oldCapture
);
var
newType
=
GetType
(
newCapture
);
if
(!
s_assemblyEqualityComparer
.
Equals
(
oldType
,
newType
))
var
oldTypeOpt
=
GetType
(
oldCapture
);
var
newTypeOpt
=
GetType
(
newCapture
);
if
(!
s_assemblyEqualityComparer
.
Equals
(
oldTypeOpt
,
newTypeOpt
))
{
diagnostics
.
Add
(
new
RudeEditDiagnostic
(
RudeEditKind
.
ChangingCapturedVariableType
,
newSyntaxOpt
.
Span
,
null
,
new
[]
{
newCapture
.
Name
,
oldType
.
ToDisplayString
(
ErrorDisplayFormat
)
}));
new
[]
{
newCapture
.
Name
,
oldType
Opt
.
ToDisplayString
(
ErrorDisplayFormat
)
}));
hasErrors
=
true
;
continue
;
}
// Parameter capture can't be changed to local capture and vice versa
// because parameters can't be introduced or deleted during EnC
// (we checked above for changes in lambda signatures).
Debug
.
Assert
(
oldCapture
.
Kind
==
newCapture
.
Kind
);
// scope check:
SyntaxNode
oldScopeOpt
=
GetCapturedVariableScope
(
oldCapture
,
oldMemberBody
,
cancellationToken
);
SyntaxNode
newScopeOpt
=
GetCapturedVariableScope
(
newCapture
,
newMemberBody
,
cancellationToken
);
...
...
@@ -3108,11 +3123,23 @@ private void ReportLambdaSignatureRudeEdits(SemanticModel oldModel, SyntaxNode o
private
static
ITypeSymbol
GetType
(
ISymbol
localOrParameter
)
{
return
(
localOrParameter
.
Kind
==
SymbolKind
.
Parameter
)
?
((
IParameterSymbol
)
localOrParameter
).
Type
:
((
ILocalSymbol
)
localOrParameter
).
Type
;
switch
(
localOrParameter
.
Kind
)
{
case
SymbolKind
.
Parameter
:
return
((
IParameterSymbol
)
localOrParameter
).
Type
;
case
SymbolKind
.
Local
:
return
((
ILocalSymbol
)
localOrParameter
).
Type
;
default
:
throw
ExceptionUtilities
.
UnexpectedValue
(
localOrParameter
.
Kind
);
}
}
private
SyntaxNode
GetCapturedVariableScope
(
ISymbol
localOrParameter
,
SyntaxNode
memberBody
,
CancellationToken
cancellationToken
)
{
Debug
.
Assert
(
localOrParameter
.
Kind
!=
SymbolKind
.
RangeVariable
);
if
(
localOrParameter
.
Kind
==
SymbolKind
.
Parameter
)
{
var
member
=
localOrParameter
.
ContainingSymbol
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录