Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
6962897b
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,发现更多精彩内容 >>
提交
6962897b
编写于
3月 07, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove intermediate translation from state->diagnostic->codeaction in rename
上级
39d2b7a0
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
73 addition
and
126 deletion
+73
-126
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingCodeRefactoringProvider.cs
...n/RenameTracking/RenameTrackingCodeRefactoringProvider.cs
+6
-35
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.StateMachine.cs
...nameTracking/RenameTrackingTaggerProvider.StateMachine.cs
+24
-21
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.cs
...ementation/RenameTracking/RenameTrackingTaggerProvider.cs
+11
-36
src/EditorFeatures/Test/RenameTracking/RenameTrackingTaggerProviderTests.cs
.../Test/RenameTracking/RenameTrackingTaggerProviderTests.cs
+14
-14
src/EditorFeatures/Test/RenameTracking/RenameTrackingTestState.cs
...orFeatures/Test/RenameTracking/RenameTrackingTestState.cs
+18
-20
未找到文件。
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingCodeRefactoringProvider.cs
浏览文件 @
6962897b
...
...
@@ -21,15 +21,6 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
Name
=
nameof
(
RenameTrackingCodeRefactoringProvider
)),
Shared
]
internal
class
RenameTrackingCodeRefactoringProvider
:
CodeRefactoringProvider
{
public
const
string
DiagnosticId
=
"RenameTracking"
;
public
static
DiagnosticDescriptor
DiagnosticDescriptor
=
new
DiagnosticDescriptor
(
DiagnosticId
,
title
:
""
,
messageFormat
:
""
,
category
:
""
,
defaultSeverity
:
DiagnosticSeverity
.
Hidden
,
isEnabledByDefault
:
true
,
customTags
:
DiagnosticCustomTags
.
Microsoft
.
Append
(
WellKnownDiagnosticTags
.
NotConfigurable
));
public
const
string
RenameFromPropertyKey
=
"RenameFrom"
;
public
const
string
RenameToPropertyKey
=
"RenameTo"
;
private
readonly
ITextUndoHistoryRegistry
_undoHistoryRegistry
;
private
readonly
IEnumerable
<
IRefactorNotifyService
>
_refactorNotifyServices
;
...
...
@@ -42,37 +33,17 @@ internal class RenameTrackingCodeRefactoringProvider : CodeRefactoringProvider
_refactorNotifyServices
=
refactorNotifyServices
;
}
// Internal for testing purposes
internal
async
Task
<
Diagnostic
?>
TryGetDiagnosticAsync
(
Document
document
,
CancellationToken
cancellationToken
)
{
var
syntaxTree
=
await
document
.
GetRequiredSyntaxTreeAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
return
RenameTrackingTaggerProvider
.
TryGetDiagnostic
(
syntaxTree
,
DiagnosticDescriptor
,
cancellationToken
);
}
public
override
async
Task
ComputeRefactoringsAsync
(
CodeRefactoringContext
context
)
public
override
Task
ComputeRefactoringsAsync
(
CodeRefactoringContext
context
)
{
var
(
document
,
span
,
cancellationToken
)
=
context
;
// Ensure rename can still be invoked in this document. We reanalyze the document for
// diagnostics when rename tracking is manually dismissed, but the existence of our
// diagnostic may still be cached, so we have to double check before actually providing
// any fixes.
if
(!
RenameTrackingTaggerProvider
.
CanInvokeRename
(
document
))
return
;
var
diagnostic
=
await
TryGetDiagnosticAsync
(
document
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
diagnostic
==
null
)
return
;
var
action
=
RenameTrackingTaggerProvider
.
TryGetCodeAction
(
document
,
span
,
_refactorNotifyServices
,
_undoHistoryRegistry
,
cancellationToken
);
// user needs to be on the same line as the diagnostic location.
var
text
=
await
document
.
GetTextAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
if
(!
text
.
AreOnSameLine
(
span
.
Start
,
diagnostic
.
Location
.
SourceSpan
.
Start
))
return
;
var
action
=
RenameTrackingTaggerProvider
.
CreateCodeAction
(
document
,
diagnostic
,
_refactorNotifyServices
,
_undoHistoryRegistry
);
if
(
action
!=
null
)
context
.
RegisterRefactoring
(
action
);
return
Task
.
CompletedTask
;
}
}
}
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.StateMachine.cs
浏览文件 @
6962897b
...
...
@@ -5,8 +5,10 @@
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Diagnostics.CodeAnalysis
;
using
System.Linq
;
using
System.Threading
;
using
Microsoft.CodeAnalysis.CodeActions
;
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Editor.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Editor.Shared.Options
;
...
...
@@ -18,6 +20,7 @@
using
Microsoft.CodeAnalysis.Shared.TestHooks
;
using
Microsoft.CodeAnalysis.Text
;
using
Microsoft.VisualStudio.Text
;
using
Microsoft.VisualStudio.Text.Operations
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
...
...
@@ -263,21 +266,25 @@ internal int StoreCurrentTrackingSessionAndGenerateId()
return
index
;
}
public
bool
CanInvokeRename
(
out
TrackingSession
trackingSession
,
bool
isSmartTagCheck
=
false
,
bool
waitForResult
=
false
,
CancellationToken
cancellationToken
=
default
)
public
bool
CanInvokeRename
(
[
NotNullWhen
(
true
)]
out
TrackingSession
trackingSession
,
bool
isSmartTagCheck
=
false
,
bool
waitForResult
=
false
,
CancellationToken
cancellationToken
=
default
)
{
// This needs to be able to run on a background thread for the diagnostic.
trackingSession
=
this
.
TrackingSession
;
if
(
trackingSession
==
null
)
{
return
false
;
}
return
TryGetSyntaxFactsService
(
out
var
syntaxFactsService
)
&&
TryGetLanguageHeuristicsService
(
out
var
languageHeuristicsService
)
&&
trackingSession
.
CanInvokeRename
(
syntaxFactsService
,
languageHeuristicsService
,
isSmartTagCheck
,
waitForResult
,
cancellationToken
);
}
internal
Diagnostic
TryGetDiagnostic
(
SyntaxTree
tree
,
DiagnosticDescriptor
diagnosticDescriptor
,
CancellationToken
cancellationToken
)
internal
CodeAction
TryGetCodeAction
(
Document
document
,
SourceText
text
,
TextSpan
userSpan
,
IEnumerable
<
IRefactorNotifyService
>
refactorNotifyServices
,
ITextUndoHistoryRegistry
undoHistoryRegistry
,
CancellationToken
cancellationToken
)
{
try
{
...
...
@@ -288,26 +295,22 @@ internal Diagnostic TryGetDiagnostic(SyntaxTree tree, DiagnosticDescriptor diagn
// method. If it does, we may give an incorrect response, but the diagnostics
// engine will know that the document changed and not display the lightbulb anyway.
if
(
Buffer
.
AsTextContainer
().
CurrentText
!=
tree
.
GetText
(
cancellationToken
))
{
return
null
;
}
if
(
CanInvokeRename
(
out
var
trackingSession
,
waitForResult
:
true
,
cancellationToken
:
cancellationToken
))
if
(
Buffer
.
AsTextContainer
().
CurrentText
==
text
&&
CanInvokeRename
(
out
var
trackingSession
,
waitForResult
:
true
,
cancellationToken
:
cancellationToken
))
{
var
snapshotSpan
=
trackingSession
.
TrackingSpan
.
GetSpan
(
Buffer
.
CurrentSnapshot
);
var
textSpan
=
snapshotSpan
.
Span
.
ToTextSpan
();
var
builder
=
ImmutableDictionary
.
CreateBuilder
<
string
,
string
>();
builder
.
Add
(
RenameTrackingCodeRefactoringProvider
.
RenameFromPropertyKey
,
trackingSession
.
OriginalName
);
builder
.
Add
(
RenameTrackingCodeRefactoringProvider
.
RenameToPropertyKey
,
snapshotSpan
.
GetText
());
var
properties
=
builder
.
ToImmutable
();
var
diagnostic
=
Diagnostic
.
Create
(
diagnosticDescriptor
,
tree
.
GetLocation
(
textSpan
),
properties
);
// user needs to be on the same line as the diagnostic location.
if
(
text
.
AreOnSameLine
(
userSpan
.
Start
,
snapshotSpan
.
Start
))
{
var
title
=
string
.
Format
(
EditorFeaturesResources
.
Rename_0_to_1
,
trackingSession
.
OriginalName
,
snapshotSpan
.
GetText
());
return
diagnostic
;
return
new
RenameTrackingCodeAction
(
document
,
title
,
refactorNotifyServices
,
undoHistoryRegistry
);
}
}
return
null
;
...
...
src/EditorFeatures/Core/Implementation/RenameTracking/RenameTrackingTaggerProvider.cs
浏览文件 @
6962897b
...
...
@@ -112,18 +112,23 @@ internal static bool ResetRenameTrackingStateWorker(Workspace workspace, Documen
return
false
;
}
internal
static
Diagnostic
TryGetDiagnostic
(
SyntaxTree
tree
,
DiagnosticDescriptor
diagnosticDescriptor
,
CancellationToken
cancellationToken
)
public
static
CodeAction
TryGetCodeAction
(
Document
document
,
TextSpan
textSpan
,
IEnumerable
<
IRefactorNotifyService
>
refactorNotifyServices
,
ITextUndoHistoryRegistry
undoHistoryRegistry
,
CancellationToken
cancellationToken
)
{
try
{
// This can run on a background thread.
if
(
tree
!=
null
&&
tree
.
TryGetText
(
out
var
text
))
if
(
document
!=
null
&&
document
.
TryGetText
(
out
var
text
))
{
var
textBuffer
=
text
.
Container
.
TryGetTextBuffer
();
if
(
textBuffer
!=
null
&&
textBuffer
.
Properties
.
TryGetProperty
(
typeof
(
StateMachine
),
out
StateMachine
stateMachine
))
if
(
textBuffer
!=
null
&&
textBuffer
.
Properties
.
TryGetProperty
(
typeof
(
StateMachine
),
out
StateMachine
stateMachine
)
&&
stateMachine
.
CanInvokeRename
(
out
_
))
{
return
stateMachine
.
TryGetDiagnostic
(
tree
,
diagnosticDescriptor
,
cancellationToken
);
return
stateMachine
.
TryGetCodeAction
(
document
,
text
,
textSpan
,
refactorNotifyServices
,
undoHistoryRegistry
,
cancellationToken
);
}
}
...
...
@@ -135,22 +140,6 @@ internal static Diagnostic TryGetDiagnostic(SyntaxTree tree, DiagnosticDescripto
}
}
internal
static
CodeAction
CreateCodeAction
(
Document
document
,
Diagnostic
diagnostic
,
IEnumerable
<
IRefactorNotifyService
>
refactorNotifyServices
,
ITextUndoHistoryRegistry
undoHistoryRegistry
)
{
// This can run on a background thread.
var
message
=
string
.
Format
(
EditorFeaturesResources
.
Rename_0_to_1
,
diagnostic
.
Properties
[
RenameTrackingCodeRefactoringProvider
.
RenameFromPropertyKey
],
diagnostic
.
Properties
[
RenameTrackingCodeRefactoringProvider
.
RenameToPropertyKey
]);
return
new
RenameTrackingCodeAction
(
document
,
message
,
refactorNotifyServices
,
undoHistoryRegistry
);
}
internal
static
bool
IsRenamableIdentifier
(
Task
<
TriggerIdentifierKind
>
isRenamableIdentifierTask
,
bool
waitForResult
,
CancellationToken
cancellationToken
)
{
if
(
isRenamableIdentifierTask
.
Status
==
TaskStatus
.
RanToCompletion
&&
isRenamableIdentifierTask
.
Result
!=
TriggerIdentifierKind
.
NotRenamable
)
...
...
@@ -184,19 +173,5 @@ internal static bool WaitForIsRenamableIdentifier(Task<TriggerIdentifierKind> is
return
false
;
}
}
internal
static
bool
CanInvokeRename
(
Document
document
)
{
ITextBuffer
textBuffer
;
if
(
document
==
null
||
!
document
.
TryGetText
(
out
var
text
))
{
return
false
;
}
textBuffer
=
text
.
Container
.
TryGetTextBuffer
();
return
textBuffer
!=
null
&&
textBuffer
.
Properties
.
TryGetProperty
(
typeof
(
StateMachine
),
out
StateMachine
stateMachine
)
&&
stateMachine
.
CanInvokeRename
(
out
_
);
}
}
}
src/EditorFeatures/Test/RenameTracking/RenameTrackingTaggerProviderTests.cs
浏览文件 @
6962897b
...
...
@@ -970,12 +970,12 @@ class C$$
state
.
EditorOperations
.
InsertText
(
"at"
);
await
state
.
AssertTag
(
"C"
,
"Cat"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
state
.
SendEscape
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1139,15 +1139,15 @@ void M()
state
.
EditorOperations
.
InsertText
(
"va"
);
await
state
.
AssertTag
(
"C"
,
"va"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
state
.
EditorOperations
.
InsertText
(
"r"
);
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
state
.
EditorOperations
.
InsertText
(
"p"
);
await
state
.
AssertTag
(
"C"
,
"varp"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1166,7 +1166,7 @@ void M()
using
var
state
=
RenameTrackingTestState
.
Create
(
code
,
LanguageNames
.
CSharp
);
state
.
EditorOperations
.
Backspace
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1185,7 +1185,7 @@ End Sub
state
.
EditorOperations
.
InsertText
(
"var"
);
await
state
.
AssertTag
(
"C"
,
"var"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1206,15 +1206,15 @@ void M()
state
.
EditorOperations
.
InsertText
(
"dynami"
);
await
state
.
AssertTag
(
"C"
,
"dynami"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
state
.
EditorOperations
.
InsertText
(
"c"
);
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
state
.
EditorOperations
.
InsertText
(
"s"
);
await
state
.
AssertTag
(
"C"
,
"dynamics"
);
Assert
.
NotNull
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
NotNull
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1234,7 +1234,7 @@ void M()
state
.
EditorOperations
.
Backspace
();
state
.
EditorOperations
.
Backspace
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1253,7 +1253,7 @@ End Class
state
.
EditorOperations
.
Backspace
();
state
.
EditorOperations
.
Backspace
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1274,7 +1274,7 @@ void M()
state
.
EditorOperations
.
Backspace
();
state
.
EditorOperations
.
Backspace
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
@@ -1293,7 +1293,7 @@ End Class
state
.
EditorOperations
.
Backspace
();
state
.
EditorOperations
.
Backspace
();
await
state
.
AssertNoTag
();
Assert
.
Null
(
await
state
.
TryGet
DocumentDiagnostic
Async
());
Assert
.
Null
(
await
state
.
TryGet
CodeAction
Async
());
}
[
WpfFact
]
...
...
src/EditorFeatures/Test/RenameTracking/RenameTrackingTestState.cs
浏览文件 @
6962897b
...
...
@@ -13,6 +13,7 @@
using
Microsoft.CodeAnalysis.Diagnostics
;
using
Microsoft.CodeAnalysis.Editor.CSharp.RenameTracking
;
using
Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
;
using
Microsoft.CodeAnalysis.Editor.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Editor.Shared.Utilities
;
using
Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
;
using
Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
;
...
...
@@ -20,6 +21,7 @@
using
Microsoft.CodeAnalysis.Notification
;
using
Microsoft.CodeAnalysis.Shared.TestHooks
;
using
Microsoft.CodeAnalysis.Shared.Utilities
;
using
Microsoft.CodeAnalysis.Text
;
using
Microsoft.CodeAnalysis.Text.Shared.Extensions
;
using
Microsoft.CodeAnalysis.UnitTests.Diagnostics
;
using
Microsoft.VisualStudio.Composition
;
...
...
@@ -169,10 +171,18 @@ public async Task AssertNoTag()
Assert
.
Equal
(
0
,
tags
.
Count
());
}
public
Task
<
Diagnostic
>
TryGetDocumentDiagnosticAsync
(
Document
document
=
null
)
/// <param name="textSpan">If <see langword="null"/> the current caret position will be used.</param>
public
async
Task
<
CodeAction
>
TryGetCodeActionAsync
(
TextSpan
?
textSpan
=
null
)
{
document
??=
this
.
Workspace
.
CurrentSolution
.
GetDocument
(
_hostDocument
.
Id
);
return
_codeRefactoringProvider
.
TryGetDiagnosticAsync
(
document
,
CancellationToken
.
None
);
var
span
=
textSpan
??
new
TextSpan
(
_view
.
Caret
.
Position
.
BufferPosition
,
0
);
var
document
=
this
.
Workspace
.
CurrentSolution
.
GetDocument
(
_hostDocument
.
Id
);
var
actions
=
new
List
<
CodeAction
>();
var
context
=
new
CodeRefactoringContext
(
document
,
span
,
actions
.
Add
,
CancellationToken
.
None
);
await
_codeRefactoringProvider
.
ComputeRefactoringsAsync
(
context
);
return
actions
.
SingleOrDefault
();
}
public
async
Task
AssertTag
(
...
...
@@ -188,26 +198,14 @@ public Task<Diagnostic> TryGetDocumentDiagnosticAsync(Document document = null)
var
tag
=
tags
.
Single
();
var
document
=
this
.
Workspace
.
CurrentSolution
.
GetDocument
(
_hostDocument
.
Id
);
var
diagnostic
=
await
TryGetDocumentDiagnosticAsync
(
document
);
// There should be a single rename tracking diagnostic
Assert
.
NotNull
(
diagnostic
);
Assert
.
Equal
(
RenameTrackingCodeRefactoringProvider
.
DiagnosticId
,
diagnostic
.
Id
);
var
actions
=
new
List
<
CodeAction
>();
var
context
=
new
CodeRefactoringContext
(
document
,
diagnostic
.
Location
.
SourceSpan
,
actions
.
Add
,
CancellationToken
.
None
);
await
_codeRefactoringProvider
.
ComputeRefactoringsAsync
(
context
);
// There should only be one code action
Assert
.
Equal
(
1
,
actions
.
Count
);
Assert
.
Equal
(
string
.
Format
(
EditorFeaturesResources
.
Rename_0_to_1
,
expectedFromName
,
expectedToName
),
actions
[
0
].
Title
);
// There should only be one code action for the tag
var
codeAction
=
await
TryGetCodeActionAsync
(
tag
.
Span
.
Span
.
ToTextSpan
());
Assert
.
NotNull
(
codeAction
);
Assert
.
Equal
(
string
.
Format
(
EditorFeaturesResources
.
Rename_0_to_1
,
expectedFromName
,
expectedToName
),
codeAction
.
Title
);
if
(
invokeAction
)
{
var
operations
=
(
await
actions
[
0
]
.
GetOperationsAsync
(
CancellationToken
.
None
)).
ToArray
();
var
operations
=
(
await
codeAction
.
GetOperationsAsync
(
CancellationToken
.
None
)).
ToArray
();
Assert
.
Equal
(
1
,
operations
.
Length
);
operations
[
0
].
TryApply
(
this
.
Workspace
,
new
ProgressTracker
(),
CancellationToken
.
None
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录