Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
8c7643c7
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,发现更多精彩内容 >>
提交
8c7643c7
编写于
5月 31, 2016
作者:
T
Tomas Matousek
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Harden active statement mapping
上级
2714017c
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
204 addition
and
36 deletion
+204
-36
src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
...atures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
+49
-3
src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/Extensions.cs
...Features/CSharpTest/EditAndContinue/Helpers/Extensions.cs
+1
-1
src/EditorFeatures/Test/EditAndContinue/ActiveStatementDescription.cs
...atures/Test/EditAndContinue/ActiveStatementDescription.cs
+5
-3
src/EditorFeatures/Test/EditAndContinue/EditAndContinueTestHelpers.cs
...atures/Test/EditAndContinue/EditAndContinueTestHelpers.cs
+6
-5
src/EditorFeatures/VisualBasicTest/EditAndContinue/ActiveStatementTests.vb
...s/VisualBasicTest/EditAndContinue/ActiveStatementTests.vb
+88
-0
src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/Extensions.vb
...res/VisualBasicTest/EditAndContinue/Helpers/Extensions.vb
+1
-1
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
...Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
+7
-8
src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
...rtable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
+34
-6
src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
...ble/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
+13
-9
未找到文件。
src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
浏览文件 @
8c7643c7
...
...
@@ -1719,18 +1719,18 @@ static void Main(string[] args)
string
src2
=
@"
class C
{
<AS:1>public static readonly int
a = F(1)
;</AS:1>
<AS:1>public static readonly int
<TS:1>a = F(1)</TS:1>
;</AS:1>
public C() {}
public static int F(int a)
{
<
AS:0>return a + 1;</AS:0>
<
TS:0><AS:0>return a + 1;</AS:0></TS:0>
}
static void Main(string[] args)
{
<
AS:2>C c = new C();</A
S:2>
<
TS:2><AS:2>C c = new C();</AS:2></T
S:2>
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
...
...
@@ -7957,6 +7957,52 @@ public static int F(int a)
edits
.
VerifyRudeDiagnostics
(
active
);
}
[
Fact
]
public
void
MisplacedActiveStatement2
()
{
string
src1
=
@"
class C
{
static <AS:0>void</AS:0> Main(string[] args)
{
}
}"
;
string
src2
=
@"
class C
{
static void Main(string[] args)
<AS:0>{</AS:0>
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
);
}
[
Fact
]
public
void
MisplacedTrackingSpan1
()
{
string
src1
=
@"
class C
{
static <AS:0>void</AS:0> Main(string[] args)
{
}
}"
;
string
src2
=
@"
class C
{
static <TS:0>void</TS:0> Main(string[] args)
<AS:0>{</AS:0>
}
}"
;
var
edits
=
GetTopEdits
(
src1
,
src2
);
var
active
=
GetActiveStatements
(
src1
,
src2
);
edits
.
VerifyRudeDiagnostics
(
active
);
}
#
endregion
#
region
Unmodified
Documents
...
...
src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/Extensions.cs
浏览文件 @
8c7643c7
...
...
@@ -19,7 +19,7 @@ internal static class Extensions
CSharpEditAndContinueTestHelpers
.
Instance
.
VerifyUnchangedDocument
(
ActiveStatementsDescription
.
ClearTags
(
source
),
description
.
OldSpans
,
description
.
TrackingSpans
,
description
.
Old
TrackingSpans
,
description
.
NewSpans
,
description
.
OldRegions
,
description
.
NewRegions
);
...
...
src/EditorFeatures/Test/EditAndContinue/ActiveStatementDescription.cs
浏览文件 @
8c7643c7
...
...
@@ -17,7 +17,7 @@ internal class ActiveStatementsDescription
public
readonly
TextSpan
[]
NewSpans
;
public
readonly
ImmutableArray
<
TextSpan
>[]
OldRegions
;
public
readonly
ImmutableArray
<
TextSpan
>[]
NewRegions
;
public
readonly
TextSpan
?[]
TrackingSpans
;
public
readonly
TextSpan
?[]
Old
TrackingSpans
;
private
ActiveStatementsDescription
()
{
...
...
@@ -25,7 +25,7 @@ private ActiveStatementsDescription()
NewSpans
=
Array
.
Empty
<
TextSpan
>();
OldRegions
=
Array
.
Empty
<
ImmutableArray
<
TextSpan
>>();
NewRegions
=
Array
.
Empty
<
ImmutableArray
<
TextSpan
>>();
TrackingSpans
=
null
;
Old
TrackingSpans
=
null
;
}
public
ActiveStatementsDescription
(
string
oldSource
,
string
newSource
)
...
...
@@ -37,7 +37,9 @@ public ActiveStatementsDescription(string oldSource, string newSource)
// Tracking spans are marked in the new source since the editor moves them around as the user
// edits the source and we get their positions when analyzing the new source.
TrackingSpans
=
GetTrackingSpans
(
newSource
,
OldSpans
.
Length
);
// The EnC analyzer uses old trackign spans as hints to find matching nodes.
// After an edit the tracking spans are updated to match new active statements.
OldTrackingSpans
=
GetTrackingSpans
(
newSource
,
OldSpans
.
Length
);
}
internal
static
readonly
ActiveStatementsDescription
Empty
=
new
ActiveStatementsDescription
();
...
...
src/EditorFeatures/Test/EditAndContinue/EditAndContinueTestHelpers.cs
浏览文件 @
8c7643c7
...
...
@@ -80,9 +80,9 @@ internal abstract class EditAndContinueTestHelpers
{
var
oldActiveStatements
=
description
.
OldSpans
;
if
(
description
.
TrackingSpans
!=
null
)
if
(
description
.
Old
TrackingSpans
!=
null
)
{
Assert
.
Equal
(
oldActiveStatements
.
Length
,
description
.
TrackingSpans
.
Length
);
Assert
.
Equal
(
oldActiveStatements
.
Length
,
description
.
Old
TrackingSpans
.
Length
);
}
string
newSource
=
editScript
.
Match
.
NewRoot
.
SyntaxTree
.
ToString
();
...
...
@@ -100,9 +100,9 @@ internal abstract class EditAndContinueTestHelpers
DocumentId
documentId
=
DocumentId
.
CreateNewId
(
ProjectId
.
CreateNewId
(
"TestEnCProject"
),
"TestEnCDocument"
);
TestActiveStatementTrackingService
trackingService
;
if
(
description
.
TrackingSpans
!=
null
)
if
(
description
.
Old
TrackingSpans
!=
null
)
{
trackingService
=
new
TestActiveStatementTrackingService
(
documentId
,
description
.
TrackingSpans
);
trackingService
=
new
TestActiveStatementTrackingService
(
documentId
,
description
.
Old
TrackingSpans
);
}
else
{
...
...
@@ -156,8 +156,9 @@ internal abstract class EditAndContinueTestHelpers
}
}
if
(
description
.
TrackingSpans
!=
null
)
if
(
description
.
Old
TrackingSpans
!=
null
)
{
// Verify that the new tracking spans are equal to the new active statements.
AssertEx
.
Equal
(
trackingService
.
TrackingSpans
,
description
.
NewSpans
.
Select
(
s
=>
(
TextSpan
?)
s
));
}
}
...
...
src/EditorFeatures/VisualBasicTest/EditAndContinue/ActiveStatementTests.vb
浏览文件 @
8c7643c7
...
...
@@ -4749,6 +4749,94 @@ End Class
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
>
Public
Sub
MisplacedActiveStatement2
()
Dim
src1
=
"
Class C
<AS:0><Attr></AS:0>
Shared Sub Main()
End Sub
End Class"
Dim
src2
=
"
Class C
<Attr>
<AS:0>Shared Sub Main()</AS:0>
End Sub
End Class"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
Dim
active
=
GetActiveStatements
(
src1
,
src2
)
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
>
Public
Sub
MisplacedTrackingSpan1
()
Dim
src1
=
"
Class C
<AS:0><Attr></AS:0>
Shared Sub Main()
End Sub
End Class"
Dim
src2
=
"
Class C
<TS:0><Attr></TS:0>
<AS:0>Shared Sub Main()</AS:0>
End Sub
End Class"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
Dim
active
=
GetActiveStatements
(
src1
,
src2
)
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
>
Public
Sub
MisplacedTrackingSpan2
()
Dim
src1
=
"
Class C
Dim f = <AS:0>1</AS:0>
End Class"
Dim
src2
=
"
Class C
<TS:0>Dim</TS:0> <AS:0>f = 1</AS:0>
End Class"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
Dim
active
=
GetActiveStatements
(
src1
,
src2
)
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
>
Public
Sub
MisplacedTrackingSpan3
()
Dim
src1
=
"
Class C
Dim <AS:0>f</AS:0>, g As New C()
End Class"
Dim
src2
=
"
Class C
<TS:0>Dim</TS:0> <AS:0>f</AS:0>, g As New C()
End Class"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
Dim
active
=
GetActiveStatements
(
src1
,
src2
)
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
>
Public
Sub
MisplacedTrackingSpan4
()
Dim
src1
=
"
Class C
<AS:0>Property</AS:0> f As New C()
End Class"
Dim
src2
=
"
Class C
<TS:0>Property</TS:0> <AS:0>f As New C()</AS:0>
End Class"
Dim
edits
=
GetTopEdits
(
src1
,
src2
)
Dim
active
=
GetActiveStatements
(
src1
,
src2
)
edits
.
VerifyRudeDiagnostics
(
active
)
End
Sub
<
Fact
,
WorkItem
(
1359
,
"https://github.com/dotnet/roslyn/issues/1359"
)
>
Public
Sub
Lambdas_LeafEdits_GeneralStatement
()
Dim
src1
=
"
...
...
src/EditorFeatures/VisualBasicTest/EditAndContinue/Helpers/Extensions.vb
浏览文件 @
8c7643c7
...
...
@@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue.UnitTests
VisualBasicEditAndContinueTestHelpers
.
Instance
.
VerifyUnchangedDocument
(
ActiveStatementsDescription
.
ClearTags
(
source
),
description
.
OldSpans
,
description
.
TrackingSpans
,
description
.
Old
TrackingSpans
,
description
.
NewSpans
,
description
.
OldRegions
,
description
.
NewRegions
)
...
...
src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs
浏览文件 @
8c7643c7
...
...
@@ -270,13 +270,12 @@ protected override SyntaxNode FindStatementAndPartner(SyntaxNode declarationBody
declarationBody
=
constructor
.
Initializer
;
partnerDeclarationBodyOpt
=
partnerConstructor
?.
Initializer
;
}
else
{
Debug
.
Assert
(!(
declarationBody
is
BlockSyntax
));
}
// let's find a labeled node that encompasses the body:
position
=
declarationBody
.
SpanStart
;
}
if
(!
declarationBody
.
FullSpan
.
Contains
(
position
))
{
// invalid position, let's find a labeled node that encompasses the body:
position
=
declarationBody
.
SpanStart
;
}
SyntaxNode
node
;
...
...
@@ -284,7 +283,7 @@ protected override SyntaxNode FindStatementAndPartner(SyntaxNode declarationBody
{
SyntaxUtilities
.
FindLeafNodeAndPartner
(
declarationBody
,
position
,
partnerDeclarationBodyOpt
,
out
node
,
out
partnerOpt
);
}
else
else
{
node
=
declarationBody
.
FindToken
(
position
).
Parent
;
partnerOpt
=
null
;
...
...
@@ -453,7 +452,7 @@ protected override SyntaxNode FindEnclosingLambdaBody(SyntaxNode containerOpt, S
{
SyntaxNode
root
=
GetEncompassingAncestor
(
containerOpt
);
while
(
node
!=
root
)
while
(
node
!=
root
&&
node
!=
null
)
{
SyntaxNode
body
;
if
(
LambdaUtilities
.
IsLambdaBodyStatementOrExpression
(
node
,
out
body
))
...
...
src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs
浏览文件 @
8c7643c7
...
...
@@ -123,6 +123,7 @@ protected SyntaxNode GetEncompassingAncestor(SyntaxNode bodyOrMatchRootOpt)
/// <remarks>
/// The declaration body node may not contain the <paramref name="position"/>.
/// This happens when an active statement associated with the member is outside of its body (e.g. C# constructor).
/// If the position doesn't correspond to any statement uses the start of the <paramref name="declarationBody"/>.
/// </remarks>
protected
abstract
SyntaxNode
FindStatementAndPartner
(
SyntaxNode
declarationBody
,
int
position
,
SyntaxNode
partnerDeclarationBodyOpt
,
out
SyntaxNode
partnerOpt
,
out
int
statementPart
);
...
...
@@ -506,12 +507,26 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
lineEdits
.
AsImmutable
(),
hasSemanticErrors
:
false
);
}
catch
(
Exception
e
)
when
(
FatalError
.
ReportUnlessCanceled
(
e
))
catch
(
Exception
e
)
when
(
ReportFatalErrorAnalyzeDocumentAsync
(
baseActiveStatements
,
e
))
{
throw
ExceptionUtilities
.
Unreachable
;
}
}
// Active statements spans are usually unavailable in crash dumps due to a bug in the debugger (DevDiv #150901),
// so we stash them here in plain array (can't use immutable, see the bug) just before we report NFW.
private
static
ActiveStatementSpan
[]
s_fatalErrorBaseActiveStatements
;
private
static
bool
ReportFatalErrorAnalyzeDocumentAsync
(
ImmutableArray
<
ActiveStatementSpan
>
baseActiveStatements
,
Exception
e
)
{
if
(!(
e
is
OperationCanceledException
))
{
s_fatalErrorBaseActiveStatements
=
baseActiveStatements
.
ToArray
();
}
return
FatalError
.
ReportUnlessCanceled
(
e
);
}
internal
Dictionary
<
SyntaxNode
,
EditKind
>
BuildEditMap
(
EditScript
<
SyntaxNode
>
editScript
)
{
var
map
=
new
Dictionary
<
SyntaxNode
,
EditKind
>(
editScript
.
Edits
.
Length
);
...
...
@@ -598,7 +613,7 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
{
if
(!
editedActiveStatements
[
i
])
{
Debug
.
Assert
(
newExceptionRegions
[
i
].
IsDefault
);
Contract
.
ThrowIfFalse
(
newExceptionRegions
[
i
].
IsDefault
);
TextSpan
trackedSpan
=
default
(
TextSpan
);
bool
isTracked
=
trackingService
!=
null
&&
...
...
@@ -624,7 +639,7 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
SyntaxNode
newMember
;
bool
hasPartner
=
topMatch
.
TryGetNewNode
(
oldMember
,
out
newMember
);
Debug
.
Assert
(
hasPartner
);
Contract
.
ThrowIfFalse
(
hasPartner
);
SyntaxNode
oldBody
=
TryGetDeclarationBody
(
oldMember
,
isMember
:
true
);
SyntaxNode
newBody
=
TryGetDeclarationBody
(
newMember
,
isMember
:
true
);
...
...
@@ -645,11 +660,18 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
if
(
isTracked
&&
trackedSpan
.
Length
!=
0
&&
newMember
.
Span
.
Contains
(
trackedSpan
))
{
int
trackedStatementPart
;
var
trackedStatement
=
FindStatement
(
newBody
,
trackedSpan
.
Start
,
out
trackedStatementPart
);
Contract
.
ThrowIfNull
(
trackedStatement
);
// Adjust for active statements that cover more than the old member span.
// For example, C# variable declarators that represent field initializers:
// [|public int <<F = Expr()>>;|]
int
adjustedOldStatementStart
=
oldMember
.
FullSpan
.
Contains
(
oldStatementSpan
.
Start
)
?
oldStatementSpan
.
Start
:
oldMember
.
SpanStart
;
//
In rare cases t
he tracking span might have been moved outside of lambda.
//
T
he tracking span might have been moved outside of lambda.
// It is not an error to move the statement - we just ignore it.
var
oldEnclosingLambdaBody
=
FindEnclosingLambdaBody
(
oldBody
,
oldMember
.
FindToken
(
oldStatementSpan
.
Start
).
Parent
);
var
oldEnclosingLambdaBody
=
FindEnclosingLambdaBody
(
oldBody
,
oldMember
.
FindToken
(
adjustedOldStatement
Start
).
Parent
);
var
newEnclosingLambdaBody
=
FindEnclosingLambdaBody
(
newBody
,
trackedStatement
);
if
(
oldEnclosingLambdaBody
==
newEnclosingLambdaBody
)
{
...
...
@@ -660,8 +682,9 @@ private SyntaxNode FindStatement(SyntaxNode declarationBody, int position, out i
if
(
newStatement
==
null
)
{
Debug
.
Assert
(
statementPart
==
-
1
);
Contract
.
ThrowIfFalse
(
statementPart
==
-
1
);
FindStatementAndPartner
(
oldBody
,
oldStatementSpan
.
Start
,
newBody
,
out
newStatement
,
out
statementPart
);
Contract
.
ThrowIfNull
(
newStatement
);
}
if
(
diagnostics
.
Count
==
0
)
...
...
@@ -940,7 +963,10 @@ internal struct UpdatedMemberInfo
int
statementPart
;
var
oldStatementStart
=
oldText
.
Lines
.
GetTextSpan
(
oldActiveStatements
[
ordinal
].
Span
).
Start
;
var
oldStatementSyntax
=
FindStatement
(
oldBody
,
oldStatementStart
,
out
statementPart
);
Contract
.
ThrowIfNull
(
oldStatementSyntax
);
var
oldEnclosingLambdaBody
=
FindEnclosingLambdaBody
(
oldBody
,
oldStatementSyntax
);
if
(
oldEnclosingLambdaBody
!=
null
)
...
...
@@ -975,6 +1001,8 @@ internal struct UpdatedMemberInfo
{
int
part
;
var
newStatementSyntax
=
FindStatement
(
newBody
,
trackedSpan
.
Start
,
out
part
);
Contract
.
ThrowIfNull
(
newStatementSyntax
);
var
newEnclosingLambdaBody
=
FindEnclosingLambdaBody
(
newBody
,
newStatementSyntax
);
// The tracking span might have been moved outside of the lambda span.
...
...
src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb
浏览文件 @
8c7643c7
...
...
@@ -418,18 +418,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
End
If
End
If
Debug
.
Assert
(
declarationBody
.
Parent
.
IsKind
(
SyntaxKind
.
EqualsValue
))
Debug
.
Assert
(
declarationBody
.
Parent
.
Parent
.
IsKind
(
SyntaxKind
.
VariableDeclarator
)
AndAlso
declarationBody
.
Parent
.
Parent
.
Parent
.
IsKind
(
SyntaxKind
.
FieldDeclaration
))
If
declarationBody
.
Parent
.
IsKind
(
SyntaxKind
.
EqualsValue
)
Then
Debug
.
Assert
(
declarationBody
.
Parent
.
Parent
.
IsKind
(
SyntaxKind
.
VariableDeclarator
)
AndAlso
declarationBody
.
Parent
.
Parent
.
Parent
.
IsKind
(
SyntaxKind
.
FieldDeclaration
))
If
partnerDeclarationBodyOpt
IsNot
Nothing
Then
partnerOpt
=
partnerDeclarationBodyOpt
.
Parent
.
Parent
End
If
If
partnerDeclarationBodyOpt
IsNot
Nothing
Then
partnerOpt
=
partnerDeclarationBodyOpt
.
Parent
.
Parent
End
If
Return
declarationBody
.
Parent
.
Parent
Return
declarationBody
.
Parent
.
Parent
End
If
End
If
Debug
.
Assert
(
declarationBody
.
FullSpan
.
Contains
(
position
))
If
Not
declarationBody
.
FullSpan
.
Contains
(
position
)
Then
' invalid position, let's find a labeled node that encompasses the body:
position
=
declarationBody
.
SpanStart
End
If
Dim
node
As
SyntaxNode
=
Nothing
If
partnerDeclarationBodyOpt
IsNot
Nothing
Then
...
...
@@ -544,7 +548,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue
Protected
Overrides
Function
FindEnclosingLambdaBody
(
containerOpt
As
SyntaxNode
,
node
As
SyntaxNode
)
As
SyntaxNode
Dim
root
As
SyntaxNode
=
GetEncompassingAncestor
(
containerOpt
)
While
node
IsNot
root
While
node
IsNot
root
And
node
IsNot
Nothing
Dim
body
As
SyntaxNode
=
Nothing
If
LambdaUtilities
.
IsLambdaBodyStatementOrExpression
(
node
,
body
)
Then
Return
body
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录