Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
663d01ab
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,发现更多精彩内容 >>
提交
663d01ab
编写于
4月 28, 2015
作者:
T
Tomas Matousek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Avoid dups in a map during analysis of captured lambda parameters
上级
93b320dc
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
186 addition
and
35 deletion
+186
-35
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
...ures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
+50
-0
src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditStatementTests.vb
...VisualBasicTest/EditAndContinue/RudeEditStatementTests.vb
+43
-2
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
...s/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+19
-0
src/Features/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
...s/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
+61
-33
src/Features/VisualBasic/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
...sic/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
+13
-0
未找到文件。
src/EditorFeatures/CSharpTest/EditAndContinue/RudeEditStatementTests.cs
浏览文件 @
663d01ab
...
...
@@ -3812,6 +3812,56 @@ void F(int x1)
edits
.
VerifySemanticDiagnostics
();
}
[
Fact
,
WorkItem
(
2223
,
"https://github.com/dotnet/roslyn/issues/2223"
)]
public
void
Lambdas_Update_CapturedParameters2
()
{
var
src1
=
@"
using System;
class C
{
void F(int x1)
{
var f1 = new Func<int, int, int>((a1, a2) =>
{
var f2 = new Func<int, int>(a3 => x1 + a2);
return a1;
});
var f3 = new Func<int, int, int>((a1, a2) =>
{
var f4 = new Func<int, int>(a3 => x1 + a2);
return a1;
});
}
}
"
;
var
src2
=
@"
using System;
class C
{
void F(int x1)
{
var f1 = new Func<int, int, int>((a1, a2) =>
{
var f2 = new Func<int, int>(a3 => x1 + a2 + 1);
return a1;
});
var f3 = new Func<int, int, int>((a1, a2) =>
{
var f4 = new Func<int, int>(a3 => x1 + a2 + 1);
return a1;
});
}
}
"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
edits
.
VerifySemanticDiagnostics
();
}
[
Fact
]
public
void
Lambdas_Update_CeaseCapture_Closure1
()
{
...
...
src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditStatementTests.vb
浏览文件 @
663d01ab
...
...
@@ -3252,6 +3252,48 @@ End Class
edits
.
VerifySemanticDiagnostics
()
End
Sub
<
Fact
,
WorkItem
(
2223
,
"https://github.com/dotnet/roslyn/issues/2223"
)
>
Public
Sub
Lambdas_Update_CapturedParameters2
()
Dim
src1
=
"
Imports System
Class C
Sub F(x1 As Integer)
Dim f1 = New Func(Of Integer, Integer, Integer)(
Function(a1, a2)
Dim f2 = New Func(Of Integer, Integer)(Function(a3) x1 + a2)
Return a1
End Function)
Dim f3 = New Func(Of Integer, Integer, Integer)(
Function(a1, a2)
Dim f4 = New Func(Of Integer, Integer)(Function(a3) x1 + a2)
Return a1
End Function)
End Sub
End Class
"
Dim
src2
=
"
Imports System
Class C
Sub F(x1 As Integer)
Dim f1 = New Func(Of Integer, Integer, Integer)(
Function(a1, a2)
Dim f2 = New Func(Of Integer, Integer)(Function(a3) x1 + a2 + 1)
Return a1
End Function)
Dim f3 = New Func(Of Integer, Integer, Integer)(
Function(a1, a2)
Dim f4 = New Func(Of Integer, Integer)(Function(a3) x1 + a2 + 1)
Return a1
End Function)
End Sub
End Class
"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
edits
.
VerifySemanticDiagnostics
()
End
Sub
<
Fact
>
Public
Sub
Lambdas_Update_CeaseCapture_Closure1
()
Dim
src1
=
"
...
...
@@ -3366,9 +3408,8 @@ End Class
"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
' TODO: better location
edits
.
VerifySemanticDiagnostics
(
Diagnostic
(
RudeEditKind
.
NotCapturingVariable
,
"
F
"
,
"a1"
))
Diagnostic
(
RudeEditKind
.
NotCapturingVariable
,
"
a1
"
,
"a1"
))
End
Sub
<
Fact
>
...
...
src/Features/CSharp/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
浏览文件 @
663d01ab
...
...
@@ -1241,6 +1241,25 @@ private static TextSpan GetDiagnosticSpan(SyntaxTokenList modifiers, SyntaxNodeO
return
TextSpan
.
FromBounds
((
modifiers
.
Count
!=
0
)
?
modifiers
.
First
().
SpanStart
:
start
.
SpanStart
,
end
.
Span
.
End
);
}
internal
override
TextSpan
GetLambdaParameterDiagnosticSpan
(
SyntaxNode
lambda
,
int
ordinal
)
{
switch
(
lambda
.
Kind
())
{
case
SyntaxKind
.
ParenthesizedLambdaExpression
:
return
((
ParenthesizedLambdaExpressionSyntax
)
lambda
).
ParameterList
.
Parameters
[
ordinal
].
Identifier
.
Span
;
case
SyntaxKind
.
SimpleLambdaExpression
:
Debug
.
Assert
(
ordinal
==
0
);
return
((
SimpleLambdaExpressionSyntax
)
lambda
).
Parameter
.
Identifier
.
Span
;
case
SyntaxKind
.
AnonymousMethodExpression
:
return
((
AnonymousMethodExpressionSyntax
)
lambda
).
ParameterList
.
Parameters
[
ordinal
].
Identifier
.
Span
;
default
:
return
lambda
.
Span
;
}
}
protected
override
string
GetTopLevelDisplayName
(
SyntaxNode
node
,
EditKind
editKind
)
{
return
GetTopLevelDisplayNameImpl
(
node
,
editKind
);
...
...
src/Features/Core/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
浏览文件 @
663d01ab
...
...
@@ -216,6 +216,7 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
protected
abstract
IEnumerable
<
SyntaxNode
>
GetVariableUseSites
(
IEnumerable
<
SyntaxNode
>
roots
,
ISymbol
localOrParameter
,
SemanticModel
model
,
CancellationToken
cancellationToken
);
protected
abstract
TextSpan
GetDiagnosticSpan
(
SyntaxNode
node
,
EditKind
editKind
);
internal
abstract
TextSpan
GetLambdaParameterDiagnosticSpan
(
SyntaxNode
lambda
,
int
ordinal
);
protected
abstract
string
GetTopLevelDisplayName
(
SyntaxNode
node
,
EditKind
editKind
);
protected
abstract
string
GetStatementDisplayName
(
SyntaxNode
node
,
EditKind
editKind
);
protected
abstract
string
GetLambdaDisplayName
(
SyntaxNode
lambda
);
...
...
@@ -2968,6 +2969,45 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
}
}
private
ValueTuple
<
SyntaxNode
,
int
>
GetParameterKey
(
IParameterSymbol
parameter
,
CancellationToken
cancellationToken
)
{
var
containingLambda
=
parameter
.
ContainingSymbol
as
IMethodSymbol
;
if
(
containingLambda
?.
MethodKind
==
MethodKind
.
LambdaMethod
)
{
var
oldContainingLambdaSyntax
=
GetSymbolSyntax
(
containingLambda
,
cancellationToken
);
return
ValueTuple
.
Create
(
oldContainingLambdaSyntax
,
parameter
.
Ordinal
);
}
else
{
return
ValueTuple
.
Create
(
default
(
SyntaxNode
),
parameter
.
Ordinal
);
}
}
private
bool
TryMapParameter
(
ValueTuple
<
SyntaxNode
,
int
>
parameterKey
,
IReadOnlyDictionary
<
SyntaxNode
,
SyntaxNode
>
map
,
out
ValueTuple
<
SyntaxNode
,
int
>
mappedParameterKey
)
{
SyntaxNode
containingLambdaSyntax
=
parameterKey
.
Item1
;
int
ordinal
=
parameterKey
.
Item2
;
if
(
containingLambdaSyntax
==
null
)
{
// method parameter: no syntax, same ordinal (can't change since method signatures must match)
mappedParameterKey
=
parameterKey
;
return
true
;
}
SyntaxNode
mappedContainingLambdaSyntax
;
if
(
map
.
TryGetValue
(
containingLambdaSyntax
,
out
mappedContainingLambdaSyntax
))
{
// parameter of an existing lambda: same ordinal (can't change since lambda signatures must match),
mappedParameterKey
=
ValueTuple
.
Create
(
mappedContainingLambdaSyntax
,
ordinal
);
return
true
;
}
// no mapping
mappedParameterKey
=
default
(
ValueTuple
<
SyntaxNode
,
int
>);
return
false
;
}
private
void
CalculateCapturedVariablesMaps
(
SemanticModel
oldModel
,
ImmutableArray
<
ISymbol
>
oldCaptures
,
...
...
@@ -3017,17 +3057,19 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
// closure scopes in the new version to the previous ones, keeping empty closures around.
var
oldLocalCapturesBySyntax
=
PooledDictionary
<
SyntaxNode
,
int
>.
GetInstance
();
var
oldParameterCapturesBy
Ordinal
=
PooledDictionary
<
int
,
int
>.
GetInstance
();
var
oldParameterCapturesBy
LambdaAndOrdinal
=
PooledDictionary
<
ValueTuple
<
SyntaxNode
,
int
>
,
int
>.
GetInstance
();
for
(
int
i
=
0
;
i
<
oldCaptures
.
Length
;
i
++)
{
if
(
oldCaptures
[
i
].
Kind
==
SymbolKind
.
Parameter
)
var
oldCapture
=
oldCaptures
[
i
];
if
(
oldCapture
.
Kind
==
SymbolKind
.
Parameter
)
{
oldParameterCapturesBy
Ordinal
.
Add
(((
IParameterSymbol
)
oldCaptures
[
i
]).
Ordinal
,
i
);
oldParameterCapturesBy
LambdaAndOrdinal
.
Add
(
GetParameterKey
((
IParameterSymbol
)
oldCapture
,
cancellationToken
)
,
i
);
}
else
{
oldLocalCapturesBySyntax
.
Add
(
GetSymbolSyntax
(
oldCapture
s
[
i
]
,
cancellationToken
),
i
);
oldLocalCapturesBySyntax
.
Add
(
GetSymbolSyntax
(
oldCapture
,
cancellationToken
),
i
);
}
}
...
...
@@ -3039,11 +3081,11 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
if
(
newCapture
.
Kind
==
SymbolKind
.
Parameter
)
{
var
newParameterCapture
=
(
IParameterSymbol
)
newCapture
;
var
newParameterKey
=
GetParameterKey
(
newParameterCapture
,
cancellationToken
);
// parameters can't be reordered, deleted or added, so no syntax mapping is needed
int
ordinal
=
newParameterCapture
.
Ordinal
;
if
(!
oldParameterCapturesByOrdinal
.
TryGetValue
(
ordinal
,
out
oldCaptureIndex
))
ValueTuple
<
SyntaxNode
,
int
>
oldParameterKey
;
if
(!
TryMapParameter
(
newParameterKey
,
map
.
Reverse
,
out
oldParameterKey
)
||
!
oldParameterCapturesByLambdaAndOrdinal
.
TryGetValue
(
oldParameterKey
,
out
oldCaptureIndex
))
{
// parameter has not been captured prior the edit:
diagnostics
.
Add
(
new
RudeEditDiagnostic
(
...
...
@@ -3053,11 +3095,12 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
new
[]
{
newCapture
.
Name
}));
hasErrors
=
true
;
continue
;
}
// Remove the old parameter capture so that at the end we can use this hashset
// to identify old captures that don't have a corresponding capture in the new version:
oldParameterCapturesBy
Ordinal
.
Remove
(
ordinal
);
oldParameterCapturesBy
LambdaAndOrdinal
.
Remove
(
oldParameterKey
);
}
else
{
...
...
@@ -3152,14 +3195,15 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
// that have no corresponding captured variables in the new version.
// Report a rude edit for all such variables.
if
(
oldParameterCapturesByOrdinal
.
Count
>
0
)
if
(
oldParameterCapturesBy
LambdaAnd
Ordinal
.
Count
>
0
)
{
var
newMemberParameters
=
GetParametersWithSyntax
(
newMember
);
// uncaptured parameters:
foreach
(
var
entry
in
oldParameterCapturesByOrdinal
)
foreach
(
var
entry
in
oldParameterCapturesBy
LambdaAnd
Ordinal
)
{
int
ordinal
=
entry
.
Key
;
int
ordinal
=
entry
.
Key
.
Item2
;
var
oldContainingLambdaSyntax
=
entry
.
Key
.
Item1
;
int
oldCaptureIndex
=
entry
.
Value
;
var
oldCapture
=
oldCaptures
[
oldCaptureIndex
];
...
...
@@ -3169,31 +3213,15 @@ private static ImmutableArray<IParameterSymbol> GetParametersWithSyntax(ISymbol
// this parameter:
span
=
GetThisParameterDiagnosticSpan
(
newMember
);
}
else
if
(
oldC
apture
.
ContainingSymbol
==
oldMember
)
else
if
(
oldC
ontainingLambdaSyntax
!=
null
)
{
//
method or property
:
span
=
Get
VariableDiagnosticSpan
(
newMemberParameters
[
ordinal
]
);
//
lambda
:
span
=
Get
LambdaParameterDiagnosticSpan
(
oldContainingLambdaSyntax
,
ordinal
);
}
else
{
// lambda:
// We don't include lambda parameters in mapping, so we need to go thru symbols:
var
oldCaptureSyntax
=
GetSymbolSyntax
(
oldCapture
,
cancellationToken
);
var
oldContainingLambda
=
(
IMethodSymbol
)
oldModel
.
GetEnclosingSymbol
(
oldCaptureSyntax
.
SpanStart
);
// TODO: VB doesn't return lambda symbol, but the containing method (bug https://github.com/dotnet/roslyn/issues/1290)
if
(
oldContainingLambda
.
MethodKind
==
MethodKind
.
LambdaMethod
)
{
var
oldContainingLambdaSyntax
=
GetSymbolSyntax
(
oldContainingLambda
,
cancellationToken
);
var
newContainingLambdaSyntax
=
map
.
Forward
[
oldContainingLambdaSyntax
];
var
newContainingLambda
=
(
IMethodSymbol
)
newModel
.
GetEnclosingSymbol
(
newContainingLambdaSyntax
.
SpanStart
);
span
=
GetVariableDiagnosticSpan
(
newContainingLambda
.
Parameters
[
ordinal
]);
}
else
{
span
=
GetThisParameterDiagnosticSpan
(
newMember
);
}
// method or property:
span
=
GetVariableDiagnosticSpan
(
newMemberParameters
[
ordinal
]);
}
diagnostics
.
Add
(
new
RudeEditDiagnostic
(
...
...
src/Features/VisualBasic/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
浏览文件 @
663d01ab
...
...
@@ -1351,6 +1351,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
Return
TextSpan
.
FromBounds
(
startToken
.
SpanStart
,
endToken
.
Span
.
End
)
End
Function
Friend
Overrides
Function
GetLambdaParameterDiagnosticSpan
(
lambda
As
SyntaxNode
,
ordinal
As
Integer
)
As
TextSpan
Select
Case
lambda
.
Kind
Case
SyntaxKind
.
MultiLineFunctionLambdaExpression
,
SyntaxKind
.
SingleLineFunctionLambdaExpression
,
SyntaxKind
.
MultiLineSubLambdaExpression
,
SyntaxKind
.
SingleLineSubLambdaExpression
Return
DirectCast
(
lambda
,
LambdaExpressionSyntax
).
SubOrFunctionHeader
.
ParameterList
.
Parameters
(
ordinal
).
Identifier
.
Span
Case
Else
Return
lambda
.
Span
End
Select
End
Function
Protected
Overrides
Function
GetTopLevelDisplayName
(
node
As
SyntaxNode
,
editKind
As
EditKind
)
As
String
Return
GetTopLevelDisplayNameImpl
(
node
)
End
Function
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录