Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
59051436
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,发现更多精彩内容 >>
未验证
提交
59051436
编写于
9月 22, 2020
作者:
D
David
提交者:
GitHub
9月 22, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #47104 from dibarbet/razor_local_rename
Razor local rename
上级
0e3e843a
f8e9ec65
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
117 addition
and
11 deletion
+117
-11
src/VisualStudio/Core/Def/Implementation/CodeLens/RemoteCodeLensReferencesService.cs
...mplementation/CodeLens/RemoteCodeLensReferencesService.cs
+5
-0
src/VisualStudio/Core/Def/Implementation/ProjectSystem/TextEditApplication.cs
...e/Def/Implementation/ProjectSystem/TextEditApplication.cs
+19
-3
src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs
...Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs
+70
-0
src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioDocumentNavigationService.cs
...tation/Workspace/VisualStudioDocumentNavigationService.cs
+10
-5
src/Workspaces/Core/Portable/Workspace/Host/DocumentService/Extensions.cs
...ore/Portable/Workspace/Host/DocumentService/Extensions.cs
+2
-2
src/Workspaces/Core/Portable/Workspace/Host/DocumentService/IDocumentServiceProvider.cs
...orkspace/Host/DocumentService/IDocumentServiceProvider.cs
+3
-1
src/Workspaces/Core/Portable/Workspace/Workspace.cs
src/Workspaces/Core/Portable/Workspace/Workspace.cs
+8
-0
未找到文件。
src/VisualStudio/Core/Def/Implementation/CodeLens/RemoteCodeLensReferencesService.cs
浏览文件 @
59051436
...
...
@@ -169,6 +169,11 @@ public RemoteCodeLensReferencesService()
}
var
excerpter
=
document
.
Services
.
GetService
<
IDocumentExcerptService
>();
if
(
excerpter
==
null
)
{
continue
;
}
var
referenceExcerpt
=
await
excerpter
.
TryExcerptAsync
(
document
,
span
,
ExcerptMode
.
SingleLine
,
cancellationToken
).
ConfigureAwait
(
false
);
var
tooltipExcerpt
=
await
excerpter
.
TryExcerptAsync
(
document
,
span
,
ExcerptMode
.
Tooltip
,
cancellationToken
).
ConfigureAwait
(
false
);
...
...
src/VisualStudio/Core/Def/Implementation/ProjectSystem/TextEditApplication.cs
浏览文件 @
59051436
...
...
@@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#
nullable
enable
using
System.Collections.Immutable
;
using
Microsoft.CodeAnalysis.Editor.Shared.Extensions
;
using
Microsoft.CodeAnalysis.Editor.Undo
;
using
Microsoft.CodeAnalysis.Text
;
...
...
@@ -13,17 +16,30 @@ internal static class TextEditApplication
{
internal
static
void
UpdateText
(
SourceText
newText
,
ITextBuffer
buffer
,
EditOptions
options
)
{
using
var
edit
=
buffer
.
CreateEdit
(
options
,
reiteratedVersionNumber
:
null
,
editTag
:
null
);
var
oldSnapshot
=
buffer
.
CurrentSnapshot
;
var
oldText
=
oldSnapshot
.
AsText
();
var
changes
=
newText
.
GetTextChanges
(
oldText
);
UpdateText
(
changes
.
ToImmutableArray
(),
buffer
,
oldSnapshot
,
oldText
,
options
);
}
public
static
void
UpdateText
(
ImmutableArray
<
TextChange
>
textChanges
,
ITextBuffer
buffer
,
EditOptions
options
)
{
var
oldSnapshot
=
buffer
.
CurrentSnapshot
;
var
oldText
=
oldSnapshot
.
AsText
();
UpdateText
(
textChanges
,
buffer
,
oldSnapshot
,
oldText
,
options
);
}
private
static
void
UpdateText
(
ImmutableArray
<
TextChange
>
textChanges
,
ITextBuffer
buffer
,
ITextSnapshot
oldSnapshot
,
SourceText
oldText
,
EditOptions
options
)
{
using
var
edit
=
buffer
.
CreateEdit
(
options
,
reiteratedVersionNumber
:
null
,
editTag
:
null
);
if
(
CodeAnalysis
.
Workspace
.
TryGetWorkspace
(
oldText
.
Container
,
out
var
workspace
))
{
var
undoService
=
workspace
.
Services
.
GetService
<
ISourceTextUndoService
>();
var
undoService
=
workspace
.
Services
.
Get
Required
Service
<
ISourceTextUndoService
>();
undoService
.
BeginUndoTransaction
(
oldSnapshot
);
}
foreach
(
var
change
in
c
hanges
)
foreach
(
var
change
in
textC
hanges
)
{
edit
.
Replace
(
change
.
Span
.
Start
,
change
.
Span
.
Length
,
change
.
NewText
);
}
...
...
src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs
浏览文件 @
59051436
...
...
@@ -653,6 +653,76 @@ protected override void ApplyAnalyzerReferenceRemoved(ProjectId projectId, Analy
}
}
internal
override
void
ApplyMappedFileChanges
(
SolutionChanges
solutionChanges
)
{
// Get the original text changes from all documents and call the span mapping service to get span mappings for the text changes.
// Create mapped text changes using the mapped spans and original text changes' text.
// Mappings for opened razor files are retrieved via the LSP client making a request to the razor server.
// If we wait for the result on the UI thread, we will hit a bug in the LSP client that brings us to a code path
// using ConfigureAwait(true). This deadlocks as it then attempts to return to the UI thread which is already blocked by us.
// Instead, we invoke this in JTF run which will mitigate deadlocks when the ConfigureAwait(true)
// tries to switch back to the main thread in the LSP client.
// Link to LSP client bug for ConfigureAwait(true) - https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1216657
var
mappedChanges
=
_threadingContext
.
JoinableTaskFactory
.
Run
(()
=>
GetMappedTextChanges
(
solutionChanges
));
// Group the mapped text changes by file, then apply all mapped text changes for the file.
foreach
(
var
changesForFile
in
mappedChanges
)
{
// It doesn't matter which of the file's projectIds we pass to the invisible editor, so just pick the first.
var
projectId
=
changesForFile
.
Value
.
First
().
ProjectId
;
// Make sure we only take distinct changes - we'll have duplicates from different projects for linked files or multi-targeted files.
var
distinctTextChanges
=
changesForFile
.
Value
.
Select
(
change
=>
change
.
TextChange
).
Distinct
().
ToImmutableArray
();
using
var
invisibleEditor
=
new
InvisibleEditor
(
ServiceProvider
.
GlobalProvider
,
changesForFile
.
Key
,
GetHierarchy
(
projectId
),
needsSave
:
true
,
needsUndoDisabled
:
false
);
TextEditApplication
.
UpdateText
(
distinctTextChanges
,
invisibleEditor
.
TextBuffer
,
EditOptions
.
None
);
}
return
;
async
Task
<
MultiDictionary
<
string
,
(
TextChange
TextChange
,
ProjectId
ProjectId
)>>
GetMappedTextChanges
(
SolutionChanges
solutionChanges
)
{
var
filePathToMappedTextChanges
=
new
MultiDictionary
<
string
,
(
TextChange
TextChange
,
ProjectId
ProjectId
)>();
foreach
(
var
projectChanges
in
solutionChanges
.
GetProjectChanges
())
{
foreach
(
var
changedDocumentId
in
projectChanges
.
GetChangedDocuments
())
{
var
oldDocument
=
projectChanges
.
OldProject
.
GetRequiredDocument
(
changedDocumentId
);
if
(!
ShouldApplyChangesToMappedDocuments
(
oldDocument
,
out
var
mappingService
))
{
continue
;
}
var
newDocument
=
projectChanges
.
NewProject
.
GetRequiredDocument
(
changedDocumentId
);
var
textChanges
=
(
await
newDocument
.
GetTextChangesAsync
(
oldDocument
,
CancellationToken
.
None
).
ConfigureAwait
(
false
)).
ToImmutableArray
();
var
mappedSpanResults
=
await
mappingService
.
MapSpansAsync
(
oldDocument
,
textChanges
.
Select
(
tc
=>
tc
.
Span
),
CancellationToken
.
None
).
ConfigureAwait
(
false
);
Contract
.
ThrowIfFalse
(
mappedSpanResults
.
Length
==
textChanges
.
Length
);
for
(
var
i
=
0
;
i
<
mappedSpanResults
.
Length
;
i
++)
{
// Only include changes that could be mapped.
var
newText
=
textChanges
[
i
].
NewText
;
if
(!
mappedSpanResults
[
i
].
IsDefault
&&
newText
!=
null
)
{
var
newTextChange
=
new
TextChange
(
mappedSpanResults
[
i
].
Span
,
newText
);
filePathToMappedTextChanges
.
Add
(
mappedSpanResults
[
i
].
FilePath
,
(
newTextChange
,
projectChanges
.
ProjectId
));
}
}
}
}
return
filePathToMappedTextChanges
;
}
bool
ShouldApplyChangesToMappedDocuments
(
CodeAnalysis
.
Document
document
,
[
NotNullWhen
(
true
)]
out
ISpanMappingService
?
spanMappingService
)
{
spanMappingService
=
document
.
Services
.
GetService
<
ISpanMappingService
>();
// Only consider files that are mapped and that we are unable to apply changes to.
// TODO - refactor how this is determined - https://github.com/dotnet/roslyn/issues/47908
return
spanMappingService
!=
null
&&
document
?.
CanApplyChange
()
==
false
;
}
}
protected
override
void
ApplyProjectReferenceAdded
(
ProjectId
projectId
,
ProjectReference
projectReference
)
{
...
...
src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioDocumentNavigationService.cs
浏览文件 @
59051436
...
...
@@ -40,6 +40,7 @@ internal sealed class VisualStudioDocumentNavigationService : ForegroundThreadAf
private
readonly
IServiceProvider
_serviceProvider
;
private
readonly
IVsEditorAdaptersFactoryService
_editorAdaptersFactoryService
;
private
readonly
IVsRunningDocumentTable4
_runningDocumentTable
;
private
readonly
IThreadingContext
_threadingContext
;
[
ImportingConstructor
]
[
Obsolete
(
MefConstruction
.
ImportingConstructorMessage
,
error
:
true
)]
...
...
@@ -52,6 +53,7 @@ internal sealed class VisualStudioDocumentNavigationService : ForegroundThreadAf
_serviceProvider
=
serviceProvider
;
_editorAdaptersFactoryService
=
editorAdaptersFactoryService
;
_runningDocumentTable
=
(
IVsRunningDocumentTable4
)
serviceProvider
.
GetService
(
typeof
(
SVsRunningDocumentTable
));
_threadingContext
=
threadingContext
;
}
public
bool
CanNavigateToSpan
(
Workspace
workspace
,
DocumentId
documentId
,
TextSpan
textSpan
)
...
...
@@ -303,12 +305,15 @@ private bool TryNavigateToMappedFile(Workspace workspace, Document generatedDocu
return
false
;
}
private
static
MappedSpanResult
?
GetMappedSpan
(
ISpanMappingService
spanMappingService
,
Document
generatedDocument
,
TextSpan
textSpan
)
private
MappedSpanResult
?
GetMappedSpan
(
ISpanMappingService
spanMappingService
,
Document
generatedDocument
,
TextSpan
textSpan
)
{
var
results
=
System
.
Threading
.
Tasks
.
Task
.
Run
(
async
()
=>
{
return
await
spanMappingService
.
MapSpansAsync
(
generatedDocument
,
SpecializedCollections
.
SingletonEnumerable
(
textSpan
),
CancellationToken
.
None
).
ConfigureAwait
(
true
);
}).
WaitAndGetResult
(
CancellationToken
.
None
);
// Mappings for opened razor files are retrieved via the LSP client making a request to the razor server.
// If we wait for the result on the UI thread, we will hit a bug in the LSP client that brings us to a code path
// using ConfigureAwait(true). This deadlocks as it then attempts to return to the UI thread which is already blocked by us.
// Instead, we invoke this in JTF run which will mitigate deadlocks when the ConfigureAwait(true)
// tries to switch back to the main thread in the LSP client.
// Link to LSP client bug for ConfigureAwait(true) - https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1216657
var
results
=
_threadingContext
.
JoinableTaskFactory
.
Run
(()
=>
spanMappingService
.
MapSpansAsync
(
generatedDocument
,
SpecializedCollections
.
SingletonEnumerable
(
textSpan
),
CancellationToken
.
None
));
if
(!
results
.
IsDefaultOrEmpty
)
{
...
...
src/Workspaces/Core/Portable/Workspace/Host/DocumentService/Extensions.cs
浏览文件 @
59051436
...
...
@@ -14,12 +14,12 @@ public static bool CanApplyChange([NotNullWhen(returnValue: true)] this TextDocu
=>
document
?.
State
.
CanApplyChange
()
??
false
;
public
static
bool
CanApplyChange
([
NotNullWhen
(
returnValue
:
true
)]
this
TextDocumentState
?
document
)
=>
document
?.
Services
.
GetService
<
IDocumentOperationService
>().
CanApplyChange
??
false
;
=>
document
?.
Services
.
GetService
<
IDocumentOperationService
>()
?
.
CanApplyChange
??
false
;
public
static
bool
SupportsDiagnostics
([
NotNullWhen
(
returnValue
:
true
)]
this
TextDocument
?
document
)
=>
document
?.
State
.
SupportsDiagnostics
()
??
false
;
public
static
bool
SupportsDiagnostics
([
NotNullWhen
(
returnValue
:
true
)]
this
TextDocumentState
?
document
)
=>
document
?.
Services
.
GetService
<
IDocumentOperationService
>().
SupportDiagnostics
??
false
;
=>
document
?.
Services
.
GetService
<
IDocumentOperationService
>()
?
.
SupportDiagnostics
??
false
;
}
}
src/Workspaces/Core/Portable/Workspace/Host/DocumentService/IDocumentServiceProvider.cs
浏览文件 @
59051436
...
...
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#
nullable
enable
namespace
Microsoft.CodeAnalysis.Host
{
internal
interface
IDocumentServiceProvider
...
...
@@ -10,6 +12,6 @@ internal interface IDocumentServiceProvider
/// Gets a document specific service provided by the host identified by the service type.
/// If the host does not provide the service, this method returns null.
/// </summary>
TService
GetService
<
TService
>()
where
TService
:
class
,
IDocumentService
;
TService
?
GetService
<
TService
>()
where
TService
:
class
,
IDocumentService
;
}
}
src/Workspaces/Core/Portable/Workspace/Workspace.cs
浏览文件 @
59051436
...
...
@@ -1220,6 +1220,9 @@ internal virtual bool TryApplyChanges(Solution newSolution, IProgressTracker pro
progressTracker
.
ItemCompleted
();
}
// changes in mapped files outside the workspace (may span multiple projects)
this
.
ApplyMappedFileChanges
(
solutionChanges
);
// removed projects
foreach
(
var
proj
in
solutionChanges
.
GetRemovedProjects
())
{
...
...
@@ -1248,6 +1251,11 @@ internal virtual bool TryApplyChanges(Solution newSolution, IProgressTracker pro
}
}
internal
virtual
void
ApplyMappedFileChanges
(
SolutionChanges
solutionChanges
)
{
return
;
}
private
void
CheckAllowedSolutionChanges
(
SolutionChanges
solutionChanges
)
{
if
(
solutionChanges
.
GetRemovedProjects
().
Any
()
&&
!
this
.
CanApplyChange
(
ApplyChangesKind
.
RemoveProject
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录