Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
0a1fb50b
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,发现更多精彩内容 >>
提交
0a1fb50b
编写于
3月 16, 2020
作者:
C
Cyrus Najmabadi
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Work
上级
f8cdc451
变更
29
展开全部
隐藏空白更改
内联
并排
Showing
29 changed file
with
875 addition
and
870 deletion
+875
-870
eng/targets/GenerateServiceHubConfigurationFiles.targets
eng/targets/GenerateServiceHubConfigurationFiles.targets
+1
-1
src/EditorFeatures/Core/Implementation/TodoComment/ITodoListProvider.cs
...ures/Core/Implementation/TodoComment/ITodoListProvider.cs
+2
-1
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentIncrementalAnalyzer.cs
...lementation/TodoComment/TodoCommentIncrementalAnalyzer.cs
+255
-255
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentIncrementalAnalyzerProvider.cs
...ion/TodoComment/TodoCommentIncrementalAnalyzerProvider.cs
+77
-77
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentState.cs
...tures/Core/Implementation/TodoComment/TodoCommentState.cs
+118
-118
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentTokens.cs
...ures/Core/Implementation/TodoComment/TodoCommentTokens.cs
+58
-58
src/EditorFeatures/Core/Implementation/TodoComment/TodoItem.cs
...ditorFeatures/Core/Implementation/TodoComment/TodoItem.cs
+70
-70
src/EditorFeatures/Core/Implementation/TodoComment/TodoItemsUpdatedArgs.cs
...s/Core/Implementation/TodoComment/TodoItemsUpdatedArgs.cs
+3
-2
src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs
...orFeatures/TestUtilities/Remote/InProcRemostHostClient.cs
+1
-1
src/Features/Core/Portable/TodoComments/ITodoCommentService.cs
...eatures/Core/Portable/TodoComments/ITodoCommentService.cs
+0
-44
src/Features/Core/Portable/TodoComments/TodoCommentDescriptor.cs
...tures/Core/Portable/TodoComments/TodoCommentDescriptor.cs
+67
-0
src/VisualStudio/Core/Def/Implementation/TableDataSource/TodoTableItem.cs
.../Core/Def/Implementation/TableDataSource/TodoTableItem.cs
+7
-17
src/VisualStudio/Core/Def/Implementation/TableDataSource/VisualStudioBaseTodoListTable.cs
...entation/TableDataSource/VisualStudioBaseTodoListTable.cs
+3
-3
src/VisualStudio/Core/Def/Implementation/TodoComments/ITodoCommentsService.cs
...e/Def/Implementation/TodoComments/ITodoCommentsService.cs
+2
-2
src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs
...mentation/TodoComments/VisualStudioTodoCommentsService.cs
+58
-49
src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsServiceFactory.cs
...on/TodoComments/VisualStudioTodoCommentsServiceFactory.cs
+14
-6
src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs
...Studio/Core/Test.Next/Services/ServiceHubServicesTests.cs
+1
-1
src/VisualStudio/Setup/source.extension.vsixmanifest
src/VisualStudio/Setup/source.extension.vsixmanifest
+2
-2
src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs
...paces/Core/Portable/Remote/WellKnownServiceHubServices.cs
+2
-2
src/Workspaces/Core/Portable/TodoComments/IRemoteTodoCommentsService.cs
.../Core/Portable/TodoComments/IRemoteTodoCommentsService.cs
+2
-2
src/Workspaces/Core/Portable/TodoComments/ITodoCommentsServiceCallback.cs
...ore/Portable/TodoComments/ITodoCommentsServiceCallback.cs
+2
-2
src/Workspaces/Core/Portable/TodoComments/TodoCommentInfo.cs
src/Workspaces/Core/Portable/TodoComments/TodoCommentInfo.cs
+1
-1
src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_TodoComments.cs
...e/ServiceHub/Services/CodeAnalysisService_TodoComments.cs
+1
-1
src/Workspaces/Remote/ServiceHub/Services/TodoComment/DescriptorsInfo.cs
...Remote/ServiceHub/Services/TodoComment/DescriptorsInfo.cs
+0
-21
src/Workspaces/Remote/ServiceHub/Services/TodoComment/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
...ent/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
+0
-91
src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
...nts/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
+91
-0
src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs
...ces/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs
+29
-36
src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzerProvider.cs
...Comments/RemoteTodoCommentsIncrementalAnalyzerProvider.cs
+3
-3
src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsService.cs
...iceHub/Services/TodoComments/RemoteTodoCommentsService.cs
+5
-4
未找到文件。
eng/targets/GenerateServiceHubConfigurationFiles.targets
浏览文件 @
0a1fb50b
...
...
@@ -12,7 +12,7 @@
<ServiceHubService
Include=
"roslynRemoteDesignerAttributeService"
ClassName=
"Microsoft.CodeAnalysis.Remote.RemoteDesignerAttributeService"
/>
<ServiceHubService
Include=
"roslynRemoteProjectTelemetryService"
ClassName=
"Microsoft.CodeAnalysis.Remote.RemoteProjectTelemetryService"
/>
<ServiceHubService
Include=
"roslynRemoteSymbolSearchUpdateEngine"
ClassName=
"Microsoft.CodeAnalysis.Remote.RemoteSymbolSearchUpdateEngine"
/>
<ServiceHubService
Include=
"roslynRemoteTodoComment
Service"
ClassName=
"Microsoft.CodeAnalysis.Remote.RemoteTodoComment
Service"
/>
<ServiceHubService
Include=
"roslynRemoteTodoComment
sService"
ClassName=
"Microsoft.CodeAnalysis.Remote.RemoteTodoComments
Service"
/>
<ServiceHubService
Include=
"roslynLanguageServer"
ClassName=
"Microsoft.CodeAnalysis.Remote.LanguageServer"
/>
</ItemGroup>
...
...
src/EditorFeatures/Core/Implementation/TodoComment/ITodoListProvider.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,6 +7,7 @@
using
System.Collections.Immutable
;
using
System.Threading
;
using
Microsoft.CodeAnalysis.Common
;
using
Microsoft.CodeAnalysis.TodoComments
;
namespace
Microsoft.CodeAnalysis.Editor
{
...
...
@@ -23,7 +24,7 @@ internal interface ITodoListProvider
/// </summary>
event
EventHandler
<
TodoItemsUpdatedArgs
>
TodoListUpdated
;
ImmutableArray
<
Todo
Item
>
GetTodoItems
(
Workspace
workspace
,
DocumentId
documentId
,
CancellationToken
cancellationToken
);
ImmutableArray
<
Todo
CommentInfo
>
GetTodoItems
(
Workspace
workspace
,
DocumentId
documentId
,
CancellationToken
cancellationToken
);
/// <summary>
/// Get current UpdatedEventArgs stored in ITodoListProvider
...
...
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentIncrementalAnalyzer.cs
浏览文件 @
0a1fb50b
此差异已折叠。
点击以展开。
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentIncrementalAnalyzerProvider.cs
浏览文件 @
0a1fb50b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
//
Licensed to the .NET Foundation under one or more agreements.
//
//
The .NET Foundation licenses this file to you under the MIT license.
//
//
See the LICENSE file in the project root for more information.
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Composition
;
using
System.Linq
;
using
System.Runtime.CompilerServices
;
using
System.Threading
;
using
Microsoft.CodeAnalysis.Common
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.SolutionCrawler
;
//
using System;
//
using System.Collections.Generic;
//
using System.Collections.Immutable;
//
using System.Composition;
//
using System.Linq;
//
using System.Runtime.CompilerServices;
//
using System.Threading;
//
using Microsoft.CodeAnalysis.Common;
//
using Microsoft.CodeAnalysis.Host;
//
using Microsoft.CodeAnalysis.SolutionCrawler;
namespace
Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
{
[
Shared
]
[
Export
(
typeof
(
ITodoListProvider
))]
[
ExportIncrementalAnalyzerProvider
(
name
:
nameof
(
TodoCommentIncrementalAnalyzerProvider
),
workspaceKinds
:
new
[]
{
WorkspaceKind
.
Host
,
WorkspaceKind
.
Interactive
,
WorkspaceKind
.
MiscellaneousFiles
})]
internal
class
TodoCommentIncrementalAnalyzerProvider
:
IIncrementalAnalyzerProvider
,
ITodoListProvider
{
private
static
readonly
ConditionalWeakTable
<
Workspace
,
TodoCommentIncrementalAnalyzer
>
s_analyzers
=
new
ConditionalWeakTable
<
Workspace
,
TodoCommentIncrementalAnalyzer
>();
//
namespace Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
//
{
//
[Shared]
//
[Export(typeof(ITodoListProvider))]
//
[ExportIncrementalAnalyzerProvider(
//
name: nameof(TodoCommentIncrementalAnalyzerProvider),
//
workspaceKinds: new[] { WorkspaceKind.Host, WorkspaceKind.Interactive, WorkspaceKind.MiscellaneousFiles })]
//
internal class TodoCommentIncrementalAnalyzerProvider : IIncrementalAnalyzerProvider, ITodoListProvider
//
{
//
private static readonly ConditionalWeakTable<Workspace, TodoCommentIncrementalAnalyzer> s_analyzers = new ConditionalWeakTable<Workspace, TodoCommentIncrementalAnalyzer>();
private
readonly
TodoCommentTokens
_todoCommentTokens
;
private
readonly
EventListenerTracker
<
ITodoListProvider
>
_eventListenerTracker
;
//
private readonly TodoCommentTokens _todoCommentTokens;
//
private readonly EventListenerTracker<ITodoListProvider> _eventListenerTracker;
[
ImportingConstructor
]
public
TodoCommentIncrementalAnalyzerProvider
(
TodoCommentTokens
todoCommentTokens
,
[
ImportMany
]
IEnumerable
<
Lazy
<
IEventListener
,
EventListenerMetadata
>>
eventListeners
)
{
_todoCommentTokens
=
todoCommentTokens
;
_eventListenerTracker
=
new
EventListenerTracker
<
ITodoListProvider
>(
eventListeners
,
WellKnownEventListeners
.
TodoListProvider
);
}
//
[ImportingConstructor]
//
public TodoCommentIncrementalAnalyzerProvider(
//
TodoCommentTokens todoCommentTokens,
//
[ImportMany]IEnumerable<Lazy<IEventListener, EventListenerMetadata>> eventListeners)
//
{
//
_todoCommentTokens = todoCommentTokens;
//
_eventListenerTracker = new EventListenerTracker<ITodoListProvider>(eventListeners, WellKnownEventListeners.TodoListProvider);
//
}
public
IIncrementalAnalyzer
CreateIncrementalAnalyzer
(
Workspace
workspace
)
{
return
s_analyzers
.
GetValue
(
workspace
,
w
=>
new
TodoCommentIncrementalAnalyzer
(
w
,
this
,
_todoCommentTokens
));
}
//
public IIncrementalAnalyzer CreateIncrementalAnalyzer(Workspace workspace)
//
{
//
return s_analyzers.GetValue(workspace, w =>
//
new TodoCommentIncrementalAnalyzer(w, this, _todoCommentTokens));
//
}
internal
void
RaiseTaskListUpdated
(
object
id
,
Workspace
workspace
,
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
,
ImmutableArray
<
TodoItem
>
items
)
{
_eventListenerTracker
.
EnsureEventListener
(
workspace
,
this
);
//
internal void RaiseTaskListUpdated(object id, Workspace workspace, Solution solution, ProjectId projectId, DocumentId documentId, ImmutableArray<TodoItem> items)
//
{
//
_eventListenerTracker.EnsureEventListener(workspace, this);
this
.
TodoListUpdated
?.
Invoke
(
this
,
new
TodoItemsUpdatedArgs
(
Tuple
.
Create
(
this
,
id
),
workspace
,
solution
,
projectId
,
documentId
,
items
));
}
//
this.TodoListUpdated?.Invoke(this, new TodoItemsUpdatedArgs(Tuple.Create(this, id), workspace, solution, projectId, documentId, items));
//
}
public
event
EventHandler
<
TodoItemsUpdatedArgs
>
TodoListUpdated
;
//
public event EventHandler<TodoItemsUpdatedArgs> TodoListUpdated;
public
ImmutableArray
<
TodoItem
>
GetTodoItems
(
Workspace
workspace
,
DocumentId
documentId
,
CancellationToken
cancellationToken
)
{
var
analyzer
=
TryGetAnalyzer
(
workspace
);
if
(
analyzer
==
null
)
{
return
ImmutableArray
<
TodoItem
>.
Empty
;
}
//
public ImmutableArray<TodoItem> GetTodoItems(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
//
{
//
var analyzer = TryGetAnalyzer(workspace);
//
if (analyzer == null)
//
{
//
return ImmutableArray<TodoItem>.Empty;
//
}
var
document
=
workspace
.
CurrentSolution
.
GetDocument
(
documentId
);
if
(
document
==
null
)
{
return
ImmutableArray
<
TodoItem
>.
Empty
;
}
//
var document = workspace.CurrentSolution.GetDocument(documentId);
//
if (document == null)
//
{
//
return ImmutableArray<TodoItem>.Empty;
//
}
return
analyzer
.
GetTodoItems
(
workspace
,
document
.
Id
,
cancellationToken
);
}
//
return analyzer.GetTodoItems(workspace, document.Id, cancellationToken);
//
}
public
IEnumerable
<
UpdatedEventArgs
>
GetTodoItemsUpdatedEventArgs
(
Workspace
workspace
,
CancellationToken
cancellationToken
)
{
var
analyzer
=
TryGetAnalyzer
(
workspace
);
if
(
analyzer
==
null
)
{
return
ImmutableArray
<
UpdatedEventArgs
>.
Empty
;
}
//
public IEnumerable<UpdatedEventArgs> GetTodoItemsUpdatedEventArgs(Workspace workspace, CancellationToken cancellationToken)
//
{
//
var analyzer = TryGetAnalyzer(workspace);
//
if (analyzer == null)
//
{
//
return ImmutableArray<UpdatedEventArgs>.Empty;
//
}
return
analyzer
.
GetTodoItemsUpdatedEventArgs
(
workspace
);
}
//
return analyzer.GetTodoItemsUpdatedEventArgs(workspace);
//
}
private
TodoCommentIncrementalAnalyzer
TryGetAnalyzer
(
Workspace
workspace
)
{
if
(
s_analyzers
.
TryGetValue
(
workspace
,
out
var
analyzer
))
{
return
analyzer
;
}
//
private TodoCommentIncrementalAnalyzer TryGetAnalyzer(Workspace workspace)
//
{
//
if (s_analyzers.TryGetValue(workspace, out var analyzer))
//
{
//
return analyzer;
//
}
return
null
;
}
}
}
//
return null;
//
}
//
}
//
}
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentState.cs
浏览文件 @
0a1fb50b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Collections.Immutable
;
using
System.IO
;
using
System.Threading
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.SolutionCrawler
;
using
Microsoft.CodeAnalysis.SolutionCrawler.State
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
{
internal
partial
class
TodoCommentIncrementalAnalyzer
:
IIncrementalAnalyzer
{
private
class
TodoCommentState
:
AbstractDocumentAnalyzerState
<
Data
>
{
private
const
string
FormatVersion
=
"1"
;
protected
override
string
StateName
=>
"<TodoComments>"
;
protected
override
int
GetCount
(
Data
data
)
{
return
data
.
Items
.
Length
;
}
protected
override
Data
TryGetExistingData
(
Stream
stream
,
Document
value
,
CancellationToken
cancellationToken
)
{
using
var
reader
=
ObjectReader
.
TryGetReader
(
stream
,
leaveOpen
:
true
,
cancellationToken
);
if
(
reader
!=
null
)
{
var
format
=
reader
.
ReadString
();
if
(
string
.
Equals
(
format
,
FormatVersion
))
{
var
textVersion
=
VersionStamp
.
ReadFrom
(
reader
);
var
dataVersion
=
VersionStamp
.
ReadFrom
(
reader
);
using
var
listDisposer
=
ArrayBuilder
<
TodoItem
>.
GetInstance
(
out
var
list
);
AppendItems
(
reader
,
value
,
list
,
cancellationToken
);
return
new
Data
(
textVersion
,
dataVersion
,
list
.
ToImmutable
());
}
}
return
null
;
}
protected
override
void
WriteTo
(
Stream
stream
,
Data
data
,
CancellationToken
cancellationToken
)
{
using
var
writer
=
new
ObjectWriter
(
stream
,
leaveOpen
:
true
,
cancellationToken
:
cancellationToken
);
writer
.
WriteString
(
FormatVersion
);
data
.
TextVersion
.
WriteTo
(
writer
);
data
.
SyntaxVersion
.
WriteTo
(
writer
);
writer
.
WriteInt32
(
data
.
Items
.
Length
);
foreach
(
var
item
in
data
.
Items
.
OfType
<
TodoItem
>())
{
cancellationToken
.
ThrowIfCancellationRequested
();
writer
.
WriteInt32
(
item
.
Priority
);
writer
.
WriteString
(
item
.
Message
);
writer
.
WriteString
(
item
.
OriginalFilePath
);
writer
.
WriteInt32
(
item
.
OriginalLine
);
writer
.
WriteInt32
(
item
.
OriginalColumn
);
writer
.
WriteString
(
item
.
MappedFilePath
);
writer
.
WriteInt32
(
item
.
MappedLine
);
writer
.
WriteInt32
(
item
.
MappedColumn
);
}
}
public
ImmutableArray
<
DocumentId
>
GetDocumentIds
()
{
return
DataCache
.
Keys
.
ToImmutableArrayOrEmpty
();
}
public
ImmutableArray
<
TodoItem
>
GetItems_TestingOnly
(
DocumentId
documentId
)
{
if
(
this
.
DataCache
.
TryGetValue
(
documentId
,
out
var
entry
)
&&
entry
.
HasCachedData
)
{
return
entry
.
Data
.
Items
;
}
return
ImmutableArray
<
TodoItem
>.
Empty
;
}
private
void
AppendItems
(
ObjectReader
reader
,
Document
document
,
ArrayBuilder
<
TodoItem
>
list
,
CancellationToken
cancellationToken
)
{
var
count
=
reader
.
ReadInt32
();
for
(
var
i
=
0
;
i
<
count
;
i
++)
{
cancellationToken
.
ThrowIfCancellationRequested
();
var
priority
=
reader
.
ReadInt32
();
var
message
=
reader
.
ReadString
();
var
originalFile
=
reader
.
ReadString
();
var
originalLine
=
reader
.
ReadInt32
();
var
originalColumn
=
reader
.
ReadInt32
();
var
mappedFile
=
reader
.
ReadString
();
var
mappedLine
=
reader
.
ReadInt32
();
var
mappedColumn
=
reader
.
ReadInt32
();
list
.
Add
(
new
TodoItem
(
priority
,
message
,
document
.
Id
,
mappedLine
,
originalLine
,
mappedColumn
,
originalColumn
,
mappedFile
,
originalFile
));
}
}
}
}
}
//
//
Licensed to the .NET Foundation under one or more agreements.
//
//
The .NET Foundation licenses this file to you under the MIT license.
//
//
See the LICENSE file in the project root for more information.
//
using System.Collections.Immutable;
//
using System.IO;
//
using System.Threading;
//
using Microsoft.CodeAnalysis.PooledObjects;
//
using Microsoft.CodeAnalysis.SolutionCrawler;
//
using Microsoft.CodeAnalysis.SolutionCrawler.State;
//
using Roslyn.Utilities;
//
namespace Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
//
{
//
internal partial class TodoCommentIncrementalAnalyzer : IIncrementalAnalyzer
//
{
//
private class TodoCommentState : AbstractDocumentAnalyzerState<Data>
//
{
//
private const string FormatVersion = "1";
//
protected override string StateName => "<TodoComments>";
//
protected override int GetCount(Data data)
//
{
//
return data.Items.Length;
//
}
//
protected override Data TryGetExistingData(Stream stream, Document value, CancellationToken cancellationToken)
//
{
//
using var reader = ObjectReader.TryGetReader(stream, leaveOpen: true, cancellationToken);
//
if (reader != null)
//
{
//
var format = reader.ReadString();
//
if (string.Equals(format, FormatVersion))
//
{
//
var textVersion = VersionStamp.ReadFrom(reader);
//
var dataVersion = VersionStamp.ReadFrom(reader);
//
using var listDisposer = ArrayBuilder<TodoItem>.GetInstance(out var list);
//
AppendItems(reader, value, list, cancellationToken);
//
return new Data(textVersion, dataVersion, list.ToImmutable());
//
}
//
}
//
return null;
//
}
//
protected override void WriteTo(Stream stream, Data data, CancellationToken cancellationToken)
//
{
//
using var writer = new ObjectWriter(stream, leaveOpen: true, cancellationToken: cancellationToken);
//
writer.WriteString(FormatVersion);
//
data.TextVersion.WriteTo(writer);
//
data.SyntaxVersion.WriteTo(writer);
//
writer.WriteInt32(data.Items.Length);
//
foreach (var item in data.Items.OfType<TodoItem>())
//
{
//
cancellationToken.ThrowIfCancellationRequested();
//
writer.WriteInt32(item.Priority);
//
writer.WriteString(item.Message);
//
writer.WriteString(item.OriginalFilePath);
//
writer.WriteInt32(item.OriginalLine);
//
writer.WriteInt32(item.OriginalColumn);
//
writer.WriteString(item.MappedFilePath);
//
writer.WriteInt32(item.MappedLine);
//
writer.WriteInt32(item.MappedColumn);
//
}
//
}
//
public ImmutableArray<DocumentId> GetDocumentIds()
//
{
//
return DataCache.Keys.ToImmutableArrayOrEmpty();
//
}
//
public ImmutableArray<TodoItem> GetItems_TestingOnly(DocumentId documentId)
//
{
//
if (this.DataCache.TryGetValue(documentId, out var entry) && entry.HasCachedData)
//
{
//
return entry.Data.Items;
//
}
//
return ImmutableArray<TodoItem>.Empty;
//
}
//
private void AppendItems(ObjectReader reader, Document document, ArrayBuilder<TodoItem> list, CancellationToken cancellationToken)
//
{
//
var count = reader.ReadInt32();
//
for (var i = 0; i < count; i++)
//
{
//
cancellationToken.ThrowIfCancellationRequested();
//
var priority = reader.ReadInt32();
//
var message = reader.ReadString();
//
var originalFile = reader.ReadString();
//
var originalLine = reader.ReadInt32();
//
var originalColumn = reader.ReadInt32();
//
var mappedFile = reader.ReadString();
//
var mappedLine = reader.ReadInt32();
//
var mappedColumn = reader.ReadInt32();
//
list.Add(new TodoItem(
//
priority, message,
//
document.Id,
//
mappedLine, originalLine, mappedColumn, originalColumn, mappedFile, originalFile));
//
}
//
}
//
}
//
}
//
}
src/EditorFeatures/Core/Implementation/TodoComment/TodoCommentTokens.cs
浏览文件 @
0a1fb50b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.ComponentModel.Composition
;
using
System.Globalization
;
using
System.Threading
;
using
Microsoft.CodeAnalysis.TodoComments
;
namespace
Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
{
/// <summary>
/// provide comment tokens to scan
///
/// we use this indirection so that we can get different tokens based on host
/// </summary>
[
Export
]
internal
class
TodoCommentTokens
{
[
ImportingConstructor
]
public
TodoCommentTokens
()
{
}
private
class
TokenInfo
{
internal
readonly
string
OptionText
;
internal
readonly
ImmutableArray
<
TodoCommentDescriptor
>
Tokens
;
public
TokenInfo
(
string
optionText
,
ImmutableArray
<
TodoCommentDescriptor
>
tokens
)
{
this
.
OptionText
=
optionText
;
this
.
Tokens
=
tokens
;
}
}
private
TokenInfo
_lastTokenInfo
;
public
ImmutableArray
<
TodoCommentDescriptor
>
GetTokens
(
Document
document
)
{
var
optionText
=
document
.
Project
.
Solution
.
Options
.
GetOption
(
TodoCommentOptions
.
TokenList
);
var
lastInfo
=
_lastTokenInfo
;
if
(
lastInfo
!=
null
&&
lastInfo
.
OptionText
==
optionText
)
{
return
lastInfo
.
Tokens
;
}
var
tokens
=
Parse
(
optionText
);
System
.
Threading
.
Interlocked
.
CompareExchange
(
ref
_lastTokenInfo
,
new
TokenInfo
(
optionText
,
tokens
),
lastInfo
);
return
tokens
;
}
}
}
//
//
Licensed to the .NET Foundation under one or more agreements.
//
//
The .NET Foundation licenses this file to you under the MIT license.
//
//
See the LICENSE file in the project root for more information.
//
using System.Collections.Generic;
//
using System.Collections.Immutable;
//
using System.ComponentModel.Composition;
//
using System.Globalization;
//
using System.Threading;
//
using Microsoft.CodeAnalysis.TodoComments;
//
namespace Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
//
{
//
/// <summary>
//
/// provide comment tokens to scan
//
///
//
/// we use this indirection so that we can get different tokens based on host
//
/// </summary>
//
[Export]
//
internal class TodoCommentTokens
//
{
//
[ImportingConstructor]
//
public TodoCommentTokens()
//
{
//
}
//
private class TokenInfo
//
{
//
internal readonly string OptionText;
//
internal readonly ImmutableArray<TodoCommentDescriptor> Tokens;
//
public TokenInfo(string optionText, ImmutableArray<TodoCommentDescriptor> tokens)
//
{
//
this.OptionText = optionText;
//
this.Tokens = tokens;
//
}
//
}
//
private TokenInfo _lastTokenInfo;
//
public ImmutableArray<TodoCommentDescriptor> GetTokens(Document document)
//
{
//
var optionText = document.Project.Solution.Options.GetOption(TodoCommentOptions.TokenList);
//
var lastInfo = _lastTokenInfo;
//
if (lastInfo != null && lastInfo.OptionText == optionText)
//
{
//
return lastInfo.Tokens;
//
}
//
var tokens = Parse(optionText);
//
System.Threading.Interlocked.CompareExchange(ref _lastTokenInfo, new TokenInfo(optionText, tokens), lastInfo);
//
return tokens;
//
}
//
}
//
}
src/EditorFeatures/Core/Implementation/TodoComment/TodoItem.cs
浏览文件 @
0a1fb50b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
//
Licensed to the .NET Foundation under one or more agreements.
//
//
The .NET Foundation licenses this file to you under the MIT license.
//
//
See the LICENSE file in the project root for more information.
using
System
;
using
Roslyn.Utilities
;
//
using System;
//
using Roslyn.Utilities;
namespace
Microsoft.CodeAnalysis.Editor
{
internal
sealed
class
TodoItem
:
IEquatable
<
TodoItem
>
{
public
int
Priority
{
get
;
}
public
string
Message
{
get
;
}
public
DocumentId
DocumentId
{
get
;
}
public
string
MappedFilePath
{
get
;
}
public
string
OriginalFilePath
{
get
;
}
public
int
MappedLine
{
get
;
}
public
int
MappedColumn
{
get
;
}
public
int
OriginalLine
{
get
;
}
public
int
OriginalColumn
{
get
;
}
//
namespace Microsoft.CodeAnalysis.Editor
//
{
//
internal sealed class TodoItem : IEquatable<TodoItem>
//
{
//
public int Priority { get; }
//
public string Message { get; }
//
public DocumentId DocumentId { get; }
//
public string MappedFilePath { get; }
//
public string OriginalFilePath { get; }
//
public int MappedLine { get; }
//
public int MappedColumn { get; }
//
public int OriginalLine { get; }
//
public int OriginalColumn { get; }
public
TodoItem
(
int
priority
,
string
message
,
DocumentId
documentId
,
int
mappedLine
,
int
originalLine
,
int
mappedColumn
,
int
originalColumn
,
string
mappedFilePath
,
string
originalFilePath
)
{
Contract
.
ThrowIfNull
(
documentId
);
//
public TodoItem(
//
int priority,
//
string message,
//
DocumentId documentId,
//
int mappedLine,
//
int originalLine,
//
int mappedColumn,
//
int originalColumn,
//
string mappedFilePath,
//
string originalFilePath)
//
{
//
Contract.ThrowIfNull(documentId);
Priority
=
priority
;
Message
=
message
;
//
Priority = priority;
//
Message = message;
DocumentId
=
documentId
;
//
DocumentId = documentId;
MappedLine
=
mappedLine
;
MappedColumn
=
mappedColumn
;
MappedFilePath
=
mappedFilePath
;
//
MappedLine = mappedLine;
//
MappedColumn = mappedColumn;
//
MappedFilePath = mappedFilePath;
OriginalLine
=
originalLine
;
OriginalColumn
=
originalColumn
;
OriginalFilePath
=
originalFilePath
;
}
//
OriginalLine = originalLine;
//
OriginalColumn = originalColumn;
//
OriginalFilePath = originalFilePath;
//
}
public
override
bool
Equals
(
object
obj
)
=>
obj
is
TodoItem
other
&&
Equals
(
other
);
//
public override bool Equals(object obj)
//
=> obj is TodoItem other && Equals(other);
public
override
int
GetHashCode
()
=>
GetHashCode
(
this
);
//
public override int GetHashCode()
//
=> GetHashCode(this);
public
override
string
ToString
()
=>
$"
{
Priority
}
{
Message
}
{
MappedFilePath
??
""
}
(
{
MappedLine
.
ToString
()}
,
{
MappedColumn
.
ToString
()}
) [original:
{
OriginalFilePath
??
""
}
(
{
OriginalLine
.
ToString
()}
,
{
OriginalColumn
.
ToString
()}
)"
;
//
public override string ToString()
//
=> $"{Priority} {Message} {MappedFilePath ?? ""} ({MappedLine.ToString()}, {MappedColumn.ToString()}) [original: {OriginalFilePath ?? ""} ({OriginalLine.ToString()}, {OriginalColumn.ToString()})";
public
bool
Equals
(
TodoItem
right
)
{
if
(
ReferenceEquals
(
this
,
right
))
{
return
true
;
}
//
public bool Equals(TodoItem right)
//
{
//
if (ReferenceEquals(this, right))
//
{
//
return true;
//
}
if
(
right
is
null
)
{
return
false
;
}
//
if (right is null)
//
{
//
return false;
//
}
return
DocumentId
==
right
.
DocumentId
&&
Priority
==
right
.
Priority
&&
Message
==
right
.
Message
&&
OriginalLine
==
right
.
OriginalLine
&&
OriginalColumn
==
right
.
OriginalColumn
;
}
//
return DocumentId == right.DocumentId &&
//
Priority == right.Priority &&
//
Message == right.Message &&
//
OriginalLine == right.OriginalLine &&
//
OriginalColumn == right.OriginalColumn;
//
}
public
static
int
GetHashCode
(
TodoItem
item
)
=>
Hash
.
Combine
(
item
.
DocumentId
,
Hash
.
Combine
(
item
.
Priority
,
Hash
.
Combine
(
item
.
Message
,
Hash
.
Combine
(
item
.
OriginalLine
,
Hash
.
Combine
(
item
.
OriginalColumn
,
0
)))));
}
}
//
public static int GetHashCode(TodoItem item)
//
=> Hash.Combine(item.DocumentId,
//
Hash.Combine(item.Priority,
//
Hash.Combine(item.Message,
//
Hash.Combine(item.OriginalLine,
//
Hash.Combine(item.OriginalColumn, 0)))));
//
}
//
}
src/EditorFeatures/Core/Implementation/TodoComment/TodoItemsUpdatedArgs.cs
浏览文件 @
0a1fb50b
...
...
@@ -4,6 +4,7 @@
using
System.Collections.Immutable
;
using
Microsoft.CodeAnalysis.Common
;
using
Microsoft.CodeAnalysis.TodoComments
;
namespace
Microsoft.CodeAnalysis.Editor
{
...
...
@@ -17,10 +18,10 @@ internal sealed class TodoItemsUpdatedArgs : UpdatedEventArgs
/// <summary>
/// The task items associated with the ID.
/// </summary>
public
ImmutableArray
<
Todo
Item
>
TodoItems
{
get
;
}
public
ImmutableArray
<
Todo
CommentInfo
>
TodoItems
{
get
;
}
public
TodoItemsUpdatedArgs
(
object
id
,
Workspace
workspace
,
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
,
ImmutableArray
<
Todo
Item
>
todoItems
)
object
id
,
Workspace
workspace
,
Solution
solution
,
ProjectId
projectId
,
DocumentId
documentId
,
ImmutableArray
<
Todo
CommentInfo
>
todoItems
)
:
base
(
id
,
workspace
,
projectId
,
documentId
)
{
Solution
=
solution
;
...
...
src/EditorFeatures/TestUtilities/Remote/InProcRemostHostClient.cs
浏览文件 @
0a1fb50b
...
...
@@ -169,7 +169,7 @@ public InProcRemoteServices(bool runCacheCleanup)
RegisterService
(
WellKnownServiceHubServices
.
RemoteSymbolSearchUpdateEngine
,
(
s
,
p
)
=>
new
RemoteSymbolSearchUpdateEngine
(
s
,
p
));
RegisterService
(
WellKnownServiceHubServices
.
RemoteDesignerAttributeService
,
(
s
,
p
)
=>
new
RemoteDesignerAttributeService
(
s
,
p
));
RegisterService
(
WellKnownServiceHubServices
.
RemoteProjectTelemetryService
,
(
s
,
p
)
=>
new
RemoteProjectTelemetryService
(
s
,
p
));
RegisterService
(
WellKnownServiceHubServices
.
RemoteTodoComment
Service
,
(
s
,
p
)
=>
new
RemoteTodoComment
Service
(
s
,
p
));
RegisterService
(
WellKnownServiceHubServices
.
RemoteTodoComment
sService
,
(
s
,
p
)
=>
new
RemoteTodoComments
Service
(
s
,
p
));
RegisterService
(
WellKnownServiceHubServices
.
LanguageServer
,
(
s
,
p
)
=>
new
LanguageServer
(
s
,
p
));
}
...
...
src/Features/Core/Portable/TodoComments/ITodoCommentService.cs
浏览文件 @
0a1fb50b
...
...
@@ -3,56 +3,12 @@
// See the LICENSE file in the project root for more information.
using
System.Collections.Immutable
;
using
System.Globalization
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.PooledObjects
;
namespace
Microsoft.CodeAnalysis.TodoComments
{
/// <summary>
/// Description of a TODO comment type to find in a user's comments.
/// </summary>
internal
readonly
struct
TodoCommentDescriptor
{
public
string
Text
{
get
;
}
public
int
Priority
{
get
;
}
public
TodoCommentDescriptor
(
string
text
,
int
priority
)
:
this
()
{
Text
=
text
;
Priority
=
priority
;
}
public
static
ImmutableArray
<
TodoCommentDescriptor
>
Parse
(
string
data
)
{
if
(
string
.
IsNullOrWhiteSpace
(
data
))
return
ImmutableArray
<
TodoCommentDescriptor
>.
Empty
;
var
tuples
=
data
.
Split
(
'|'
);
var
result
=
ArrayBuilder
<
TodoCommentDescriptor
>.
GetInstance
();
foreach
(
var
tuple
in
tuples
)
{
if
(
string
.
IsNullOrWhiteSpace
(
tuple
))
continue
;
var
pair
=
tuple
.
Split
(
':'
);
if
(
pair
.
Length
!=
2
||
string
.
IsNullOrWhiteSpace
(
pair
[
0
]))
continue
;
if
(!
int
.
TryParse
(
pair
[
1
],
NumberStyles
.
None
,
CultureInfo
.
InvariantCulture
,
out
var
priority
))
continue
;
result
.
Add
(
new
TodoCommentDescriptor
(
pair
[
0
].
Trim
(),
priority
));
}
return
result
.
ToImmutableAndFree
();
}
}
/// <summary>
/// A TODO comment that has been found within the user's code.
/// </summary>
...
...
src/Features/Core/Portable/TodoComments/TodoCommentDescriptor.cs
0 → 100644
浏览文件 @
0a1fb50b
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Collections.Immutable
;
using
System.Globalization
;
using
Microsoft.CodeAnalysis.PooledObjects
;
namespace
Microsoft.CodeAnalysis.TodoComments
{
/// <summary>
/// Description of a TODO comment type to find in a user's comments.
/// </summary>
internal
readonly
struct
TodoCommentDescriptor
{
public
string
Text
{
get
;
}
public
int
Priority
{
get
;
}
public
TodoCommentDescriptor
(
string
text
,
int
priority
)
:
this
()
{
Text
=
text
;
Priority
=
priority
;
}
}
internal
readonly
struct
ParsedTodoCommentDescriptors
{
/// <summary>
/// The original option text that <see cref="Descriptors"/> were parsed out of.
/// </summary>
public
readonly
string
OptionText
;
public
readonly
ImmutableArray
<
TodoCommentDescriptor
>
Descriptors
;
public
ParsedTodoCommentDescriptors
(
string
optionText
,
ImmutableArray
<
TodoCommentDescriptor
>
descriptors
)
{
this
.
OptionText
=
optionText
;
this
.
Descriptors
=
descriptors
;
}
public
static
ParsedTodoCommentDescriptors
Parse
(
string
data
)
{
if
(
string
.
IsNullOrWhiteSpace
(
data
))
return
new
ParsedTodoCommentDescriptors
(
data
,
ImmutableArray
<
TodoCommentDescriptor
>.
Empty
);
var
tuples
=
data
.
Split
(
'|'
);
var
result
=
ArrayBuilder
<
TodoCommentDescriptor
>.
GetInstance
();
foreach
(
var
tuple
in
tuples
)
{
if
(
string
.
IsNullOrWhiteSpace
(
tuple
))
continue
;
var
pair
=
tuple
.
Split
(
':'
);
if
(
pair
.
Length
!=
2
||
string
.
IsNullOrWhiteSpace
(
pair
[
0
]))
continue
;
if
(!
int
.
TryParse
(
pair
[
1
],
NumberStyles
.
None
,
CultureInfo
.
InvariantCulture
,
out
var
priority
))
continue
;
result
.
Add
(
new
TodoCommentDescriptor
(
pair
[
0
].
Trim
(),
priority
));
}
return
new
ParsedTodoCommentDescriptors
(
data
,
result
.
ToImmutableAndFree
());
}
}
}
src/VisualStudio/Core/Def/Implementation/TableDataSource/TodoTableItem.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,28 +7,28 @@
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.Editor
;
using
Microsoft.CodeAnalysis.Text
;
using
Microsoft.CodeAnalysis.TodoComments
;
using
Roslyn.Utilities
;
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
internal
sealed
class
TodoTableItem
:
TableItem
{
public
readonly
Todo
Item
Data
;
public
readonly
Todo
CommentInfo
Data
;
private
TodoTableItem
(
Workspace
workspace
,
Todo
Item
data
,
Todo
CommentInfo
data
,
string
projectName
,
Guid
projectGuid
,
string
[]
projectNames
,
Guid
[]
projectGuids
)
:
base
(
workspace
,
projectName
,
projectGuid
,
projectNames
,
projectGuids
)
{
Contract
.
ThrowIfNull
(
data
);
Data
=
data
;
}
public
static
TodoTableItem
Create
(
Workspace
workspace
,
Todo
Item
data
)
public
static
TodoTableItem
Create
(
Workspace
workspace
,
Todo
CommentInfo
data
)
{
GetProjectNameAndGuid
(
workspace
,
data
.
DocumentId
.
ProjectId
,
out
var
projectName
,
out
var
projectGuid
);
return
new
TodoTableItem
(
workspace
,
data
,
projectName
,
projectGuid
,
projectNames
:
Array
.
Empty
<
string
>(),
projectGuids
:
Array
.
Empty
<
Guid
>());
...
...
@@ -66,29 +66,19 @@ public override bool EqualsIgnoringLocation(TableItem other)
/// We want to avoid displaying diagnostic multuple times when it is reported from
/// multi-targeted projects and/or files linked to multiple projects.
/// </summary>
internal
sealed
class
GroupingComparer
:
IEqualityComparer
<
Todo
Item
>,
IEqualityComparer
<
TodoTableItem
>
internal
sealed
class
GroupingComparer
:
IEqualityComparer
<
Todo
CommentInfo
>,
IEqualityComparer
<
TodoTableItem
>
{
public
static
readonly
GroupingComparer
Instance
=
new
GroupingComparer
();
public
bool
Equals
(
Todo
Item
left
,
TodoItem
right
)
public
bool
Equals
(
Todo
CommentInfo
left
,
TodoCommentInfo
right
)
{
if
(
ReferenceEquals
(
left
,
right
))
{
return
true
;
}
if
(
left
is
null
||
right
is
null
)
{
return
false
;
}
// We don't need to compare OriginalFilePath since TODO items are only aggregated within a single file.
return
left
.
OriginalLine
==
right
.
OriginalLine
&&
left
.
OriginalColumn
==
right
.
OriginalColumn
;
}
public
int
GetHashCode
(
Todo
Item
data
)
public
int
GetHashCode
(
Todo
CommentInfo
data
)
=>
Hash
.
Combine
(
data
.
OriginalLine
,
data
.
OriginalColumn
);
public
bool
Equals
(
TodoTableItem
left
,
TodoTableItem
right
)
...
...
src/VisualStudio/Core/Def/Implementation/TableDataSource/VisualStudioBaseTodoListTable.cs
浏览文件 @
0a1fb50b
...
...
@@ -237,13 +237,13 @@ public override bool TryGetValue(int index, string columnName, out object conten
switch
(
columnName
)
{
case
StandardTableKeyNames
.
Priority
:
content
=
ValueTypeCache
.
GetOrCreate
((
VSTASKPRIORITY
)
data
.
Priority
);
content
=
ValueTypeCache
.
GetOrCreate
((
VSTASKPRIORITY
)
data
.
Value
.
Priority
);
return
content
!=
null
;
case
StandardTableKeyNames
.
Text
:
content
=
data
.
Message
;
content
=
data
.
Value
.
Message
;
return
content
!=
null
;
case
StandardTableKeyNames
.
DocumentName
:
content
=
GetFileName
(
data
.
OriginalFilePath
,
data
.
MappedFilePath
);
content
=
GetFileName
(
data
.
Value
.
OriginalFilePath
,
data
.
Value
.
MappedFilePath
);
return
content
!=
null
;
case
StandardTableKeyNames
.
Line
:
content
=
GetLineColumn
(
item
).
Line
;
...
...
src/VisualStudio/Core/Def/Implementation/TodoComment
/ITodoComment
Service.cs
→
src/VisualStudio/Core/Def/Implementation/TodoComment
s/ITodoComments
Service.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,12 +7,12 @@
using
System.Threading
;
using
Microsoft.CodeAnalysis.Host
;
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
s
{
/// <summary>
/// In process service responsible for listening to OOP todo comment notifications.
/// </summary>
internal
interface
ITodoCommentService
:
IWorkspaceService
internal
interface
ITodoComment
s
Service
:
IWorkspaceService
{
/// <summary>
/// Called by a host to let this service know that it should start background
...
...
src/VisualStudio/Core/Def/Implementation/TodoComment
/VisualStudioTodoComment
Service.cs
→
src/VisualStudio/Core/Def/Implementation/TodoComment
s/VisualStudioTodoComments
Service.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,27 +7,32 @@
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.Linq
;
using
System.Runtime.CompilerServices
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.Common
;
using
Microsoft.CodeAnalysis.Editor
;
using
Microsoft.CodeAnalysis.Editor.Shared.Utilities
;
using
Microsoft.CodeAnalysis.ErrorReporting
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.ProjectTelemetry
;
using
Microsoft.CodeAnalysis.Remote
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.TodoComment
;
using
Microsoft.CodeAnalysis.TodoComments
;
using
Microsoft.Internal.VisualStudio.Shell
;
using
Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
;
using
Roslyn.Utilities
;
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
s
{
internal
class
VisualStudioTodoCommentService
:
ForegroundThreadAffinitizedObject
,
ITodoComment
Service
,
ITodoCommentServiceCallback
internal
class
VisualStudioTodoComment
s
Service
:
ForegroundThreadAffinitizedObject
,
ITodoComment
sService
,
ITodoCommentsServiceCallback
,
ITodoListProvider
{
private
readonly
VisualStudioWorkspaceImpl
_workspace
;
private
readonly
EventListenerTracker
<
ITodoListProvider
>
_eventListenerTracker
;
private
readonly
ConditionalWeakTable
<
DocumentId
,
StrongBox
<
ImmutableArray
<
TodoCommentInfo
>>>
_documentToInfos
=
new
ConditionalWeakTable
<
DocumentId
,
StrongBox
<
ImmutableArray
<
TodoCommentInfo
>>>();
/// <summary>
/// Our connections to the remote OOP server. Created on demand when we startup and then
...
...
@@ -40,10 +45,19 @@ internal class VisualStudioTodoCommentService
/// </summary>
private
AsyncBatchingWorkQueue
<
TodoCommentInfo
>
_workQueue
=
null
!;
public
VisualStudioTodoCommentService
(
VisualStudioWorkspaceImpl
workspace
,
IThreadingContext
threadingContext
)
:
base
(
threadingContext
)
=>
_workspace
=
workspace
;
public
event
EventHandler
<
TodoItemsUpdatedArgs
>?
TodoListUpdated
;
public
VisualStudioTodoCommentsService
(
VisualStudioWorkspaceImpl
workspace
,
IThreadingContext
threadingContext
,
EventListenerTracker
<
ITodoListProvider
>
eventListenerTracker
)
:
base
(
threadingContext
)
{
_workspace
=
workspace
;
_eventListenerTracker
=
eventListenerTracker
;
}
void
ITodoCommentService
.
Start
(
CancellationToken
cancellationToken
)
void
ITodoComment
s
Service
.
Start
(
CancellationToken
cancellationToken
)
=>
_
=
StartAsync
(
cancellationToken
);
private
async
Task
StartAsync
(
CancellationToken
cancellationToken
)
...
...
@@ -79,14 +93,17 @@ private async Task StartWorkerAsync(CancellationToken cancellationToken)
// Pass ourselves in as the callback target for the OOP service. As it discovers
// designer attributes it will call back into us to notify VS about it.
_keepAliveSession
=
await
client
.
TryCreateKeepAliveSessionAsync
(
WellKnownServiceHubServices
.
RemoteTodoCommentService
,
WellKnownServiceHubServices
.
RemoteTodoComment
s
Service
,
callbackTarget
:
this
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
_keepAliveSession
==
null
)
return
;
// Now that we've started, let the VS todo list know to start listening to us
_eventListenerTracker
.
EnsureEventListener
(
_workspace
,
this
);
// Now kick off scanning in the OOP process.
var
success
=
await
_keepAliveSession
.
TryInvokeAsync
(
nameof
(
IRemoteTodoCommentService
.
ComputeTodoCommentsAsync
),
nameof
(
IRemoteTodoComment
s
Service
.
ComputeTodoCommentsAsync
),
solution
:
null
,
arguments
:
Array
.
Empty
<
object
>(),
cancellationToken
).
ConfigureAwait
(
false
);
...
...
@@ -101,19 +118,31 @@ public Task ReportTodoCommentsAsync(List<TodoCommentInfo> infos, CancellationTok
return
Task
.
CompletedTask
;
}
private
async
Task
ProcessTodoCommentInfosAsync
(
private
Task
ProcessTodoCommentInfosAsync
(
ImmutableArray
<
TodoCommentInfo
>
infos
,
CancellationToken
cancellationToken
)
{
cancellationToken
.
ThrowIfCancellationRequested
();
using
var
_
1
=
ArrayBuilder
<
TodoCommentInfo
>.
GetInstance
(
out
var
filteredInfos
);
using
var
_
=
ArrayBuilder
<
TodoCommentInfo
>.
GetInstance
(
out
var
filteredInfos
);
AddFilteredInfos
(
infos
,
filteredInfos
);
using
var
_2
=
ArrayBuilder
<
Task
>.
GetInstance
(
out
var
tasks
);
foreach
(
var
info
in
filteredInfos
)
tasks
.
Add
(
Task
.
Run
(()
=>
NotifyTelemetryService
(
info
),
cancellationToken
));
foreach
(
var
group
in
filteredInfos
.
GroupBy
(
i
=>
i
.
DocumentId
))
{
var
documentId
=
group
.
Key
;
var
documentInfos
=
group
.
ToImmutableArray
();
// only one thread can be executing ProcessTodoCommentInfosAsync at a time,
// so it's safe to remove/add here.
_documentToInfos
.
Remove
(
documentId
);
_documentToInfos
.
Add
(
documentId
,
new
StrongBox
<
ImmutableArray
<
TodoCommentInfo
>>(
documentInfos
));
this
.
TodoListUpdated
?.
Invoke
(
this
,
new
TodoItemsUpdatedArgs
(
documentId
,
_workspace
,
_workspace
.
CurrentSolution
,
documentId
.
ProjectId
,
documentId
,
documentInfos
));
}
await
Task
.
WhenAll
(
tasks
).
ConfigureAwait
(
false
)
;
return
Task
.
CompletedTask
;
}
private
void
AddFilteredInfos
(
ImmutableArray
<
TodoCommentInfo
>
infos
,
ArrayBuilder
<
TodoCommentInfo
>
filteredInfos
)
...
...
@@ -131,38 +160,18 @@ private void AddFilteredInfos(ImmutableArray<TodoCommentInfo> infos, ArrayBuilde
}
}
p
rivate
void
ProcessTodoCommentInfosAsync
(
ProjectTelemetryInfo
info
)
p
ublic
ImmutableArray
<
TodoCommentInfo
>
GetTodoItems
(
Workspace
workspace
,
DocumentId
documentId
,
CancellationToken
cancellationToken
)
{
try
{
var
telemetryEvent
=
TelemetryHelper
.
TelemetryService
.
CreateEvent
(
TelemetryEventPath
);
telemetryEvent
.
SetStringProperty
(
TelemetryProjectIdName
,
info
.
ProjectId
.
Id
.
ToString
());
telemetryEvent
.
SetStringProperty
(
TelemetryProjectGuidName
,
Guid
.
Empty
.
ToString
());
telemetryEvent
.
SetStringProperty
(
TelemetryLanguageName
,
info
.
Language
);
telemetryEvent
.
SetIntProperty
(
TelemetryAnalyzerReferencesCountName
,
info
.
AnalyzerReferencesCount
);
telemetryEvent
.
SetIntProperty
(
TelemetryProjectReferencesCountName
,
info
.
ProjectReferencesCount
);
telemetryEvent
.
SetIntProperty
(
TelemetryMetadataReferencesCountName
,
info
.
MetadataReferencesCount
);
telemetryEvent
.
SetIntProperty
(
TelemetryDocumentsCountName
,
info
.
DocumentsCount
);
telemetryEvent
.
SetIntProperty
(
TelemetryAdditionalDocumentsCountName
,
info
.
AdditionalDocumentsCount
);
TelemetryHelper
.
DefaultTelemetrySession
.
PostEvent
(
telemetryEvent
);
}
catch
(
Exception
e
)
{
// The telemetry service itself can throw.
// So, to be very careful, put this in a try/catch too.
try
{
var
exceptionEvent
=
TelemetryHelper
.
TelemetryService
.
CreateEvent
(
TelemetryExceptionEventPath
);
exceptionEvent
.
SetStringProperty
(
"Type"
,
e
.
GetTypeDisplayName
());
exceptionEvent
.
SetStringProperty
(
"Message"
,
e
.
Message
);
exceptionEvent
.
SetStringProperty
(
"StackTrace"
,
e
.
StackTrace
);
TelemetryHelper
.
DefaultTelemetrySession
.
PostEvent
(
exceptionEvent
);
}
catch
{
}
}
return
_documentToInfos
.
TryGetValue
(
documentId
,
out
var
values
)
?
values
.
Value
:
ImmutableArray
<
TodoCommentInfo
>.
Empty
;
}
public
IEnumerable
<
UpdatedEventArgs
>
GetTodoItemsUpdatedEventArgs
(
Workspace
workspace
,
CancellationToken
cancellationToken
)
{
// Don't need to implement this. OOP pushes all items over to VS. So there's no need
return
SpecializedCollections
.
EmptyEnumerable
<
UpdatedEventArgs
>();
}
}
}
src/VisualStudio/Core/Def/Implementation/TodoComment
/VisualStudioTodoComment
ServiceFactory.cs
→
src/VisualStudio/Core/Def/Implementation/TodoComment
s/VisualStudioTodoComments
ServiceFactory.cs
浏览文件 @
0a1fb50b
...
...
@@ -5,6 +5,7 @@
#
nullable
enable
using
System
;
using
System.Collections.Generic
;
using
System.Composition
;
using
Microsoft.CodeAnalysis.Editor
;
using
Microsoft.CodeAnalysis.Editor.Shared.Utilities
;
...
...
@@ -12,25 +13,32 @@
using
Microsoft.CodeAnalysis.Host.Mef
;
using
Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
;
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
namespace
Microsoft.VisualStudio.LanguageServices.Implementation.TodoComment
s
{
[
Export
(
typeof
(
ITodoListProvider
))]
[
ExportWorkspaceServiceFactory
(
typeof
(
ITodoCommentService
),
ServiceLayer
.
Host
),
Shared
]
internal
class
VisualStudioTodoComment
ServiceFactory
:
IWorkspaceServiceFactory
,
ITodoListProvider
[
ExportWorkspaceServiceFactory
(
typeof
(
ITodoComment
s
Service
),
ServiceLayer
.
Host
),
Shared
]
internal
class
VisualStudioTodoComment
sServiceFactory
:
IWorkspaceServiceFactory
{
private
readonly
IThreadingContext
_threadingContext
;
private
readonly
EventListenerTracker
<
ITodoListProvider
>
_eventListenerTracker
;
[
ImportingConstructor
]
[
Obsolete
(
MefConstruction
.
ImportingConstructorMessage
,
error
:
true
)]
public
VisualStudioTodoCommentServiceFactory
(
IThreadingContext
threadingContext
)
=>
_threadingContext
=
threadingContext
;
public
VisualStudioTodoCommentsServiceFactory
(
IThreadingContext
threadingContext
,
[
ImportMany
]
IEnumerable
<
Lazy
<
IEventListener
,
EventListenerMetadata
>>
eventListeners
)
{
_threadingContext
=
threadingContext
;
_eventListenerTracker
=
new
EventListenerTracker
<
ITodoListProvider
>(
eventListeners
,
WellKnownEventListeners
.
TodoListProvider
);
}
public
IWorkspaceService
?
CreateService
(
HostWorkspaceServices
workspaceServices
)
{
if
(!(
workspaceServices
.
Workspace
is
VisualStudioWorkspaceImpl
workspace
))
return
null
;
return
new
VisualStudioTodoCommentService
(
workspace
,
_threadingContext
);
return
new
VisualStudioTodoCommentsService
(
workspace
,
_threadingContext
,
_eventListenerTracker
);
}
}
}
src/VisualStudio/Core/Test.Next/Services/ServiceHubServicesTests.cs
浏览文件 @
0a1fb50b
...
...
@@ -146,7 +146,7 @@ public async Task TestTodoComments()
var
comments
=
await
client
.
TryRunRemoteAsync
<
IList
<
TodoComment
>>(
WellKnownServiceHubServices
.
CodeAnalysisService
,
nameof
(
IRemoteTodoCommentService
.
GetTodoCommentsAsync
),
nameof
(
IRemoteTodoComment
s
Service
.
GetTodoCommentsAsync
),
solution
,
new
object
[]
{
solution
.
Projects
.
First
().
DocumentIds
.
First
(),
ImmutableArray
.
Create
(
new
TodoCommentDescriptor
(
"TODO"
,
0
))
},
callbackTarget
:
null
,
...
...
src/VisualStudio/Setup/source.extension.vsixmanifest
浏览文件 @
0a1fb50b
...
...
@@ -37,7 +37,7 @@
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteDesignerAttributeService.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteProjectTelemetryService.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteSymbolSearchUpdateEngine.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteTodoCommentService.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteTodoComment
s
Service.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynLanguageServer.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteHost64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynSnapshot64.servicehub.service.json"
/>
...
...
@@ -45,7 +45,7 @@
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteDesignerAttributeService64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteProjectTelemetryService64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteSymbolSearchUpdateEngine64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteTodoCommentService64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynRemoteTodoComment
s
Service64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.ServiceHub.Service"
d:Source=
"File"
Path=
"roslynLanguageServer64.servicehub.service.json"
/>
<Asset
Type=
"Microsoft.VisualStudio.MefComponent"
d:Source=
"Project"
d:ProjectName=
"BasicVisualStudio"
Path=
"|BasicVisualStudio|"
/>
<Asset
Type=
"Microsoft.VisualStudio.MefComponent"
d:Source=
"Project"
d:ProjectName=
"CSharpVisualStudio"
Path=
"|CSharpVisualStudio|"
/>
...
...
src/Workspaces/Core/Portable/Remote/WellKnownServiceHubServices.cs
浏览文件 @
0a1fb50b
...
...
@@ -15,7 +15,7 @@ public static void Set64bit(bool x64)
RemoteDesignerAttributeService
=
"roslynRemoteDesignerAttributeService"
+
bit
;
RemoteProjectTelemetryService
=
"roslynRemoteProjectTelemetryService"
+
bit
;
RemoteSymbolSearchUpdateEngine
=
"roslynRemoteSymbolSearchUpdateEngine"
+
bit
;
RemoteTodoComment
Service
=
"roslynRemoteTodoComment
Service"
+
bit
;
RemoteTodoComment
sService
=
"roslynRemoteTodoComments
Service"
+
bit
;
LanguageServer
=
"roslynLanguageServer"
+
bit
;
}
...
...
@@ -24,7 +24,7 @@ public static void Set64bit(bool x64)
public
static
string
RemoteDesignerAttributeService
{
get
;
private
set
;
}
=
"roslynRemoteDesignerAttributeService"
;
public
static
string
RemoteProjectTelemetryService
{
get
;
private
set
;
}
=
"roslynRemoteProjectTelemetryService"
;
public
static
string
RemoteSymbolSearchUpdateEngine
{
get
;
private
set
;
}
=
"roslynRemoteSymbolSearchUpdateEngine"
;
public
static
string
RemoteTodoComment
Service
{
get
;
private
set
;
}
=
"roslynRemoteTodoComment
Service"
;
public
static
string
RemoteTodoComment
sService
{
get
;
private
set
;
}
=
"roslynRemoteTodoComments
Service"
;
public
static
string
LanguageServer
{
get
;
private
set
;
}
=
"roslynLanguageServer"
;
// these are OOP implementation itself should care. not features that consume OOP care
...
...
src/Workspaces/Core/Portable/TodoComment/IRemoteTodoCommentsService.cs
→
src/Workspaces/Core/Portable/TodoComment
s
/IRemoteTodoCommentsService.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,13 +7,13 @@
using
System.Threading
;
using
System.Threading.Tasks
;
namespace
Microsoft.CodeAnalysis.TodoComment
namespace
Microsoft.CodeAnalysis.TodoComment
s
{
/// <summary>
/// Interface to allow host (VS) to inform the OOP service to start incrementally analyzing and
/// reporting results back to the host.
/// </summary>
internal
interface
IRemoteTodoCommentService
internal
interface
IRemoteTodoComment
s
Service
{
Task
ComputeTodoCommentsAsync
(
CancellationToken
cancellation
);
}
...
...
src/Workspaces/Core/Portable/TodoComment
/ITodoComment
ServiceCallback.cs
→
src/Workspaces/Core/Portable/TodoComment
s/ITodoComments
ServiceCallback.cs
浏览文件 @
0a1fb50b
...
...
@@ -8,13 +8,13 @@
using
System.Threading
;
using
System.Threading.Tasks
;
namespace
Microsoft.CodeAnalysis.TodoComment
namespace
Microsoft.CodeAnalysis.TodoComment
s
{
/// <summary>
/// Callback the host (VS) passes to the OOP service to allow it to send batch notifications
/// about todo comments.
/// </summary>
internal
interface
ITodoCommentServiceCallback
internal
interface
ITodoComment
s
ServiceCallback
{
Task
ReportTodoCommentsAsync
(
List
<
TodoCommentInfo
>
infos
,
CancellationToken
cancellationToken
);
}
...
...
src/Workspaces/Core/Portable/TodoComment/TodoCommentInfo.cs
→
src/Workspaces/Core/Portable/TodoComment
s
/TodoCommentInfo.cs
浏览文件 @
0a1fb50b
...
...
@@ -7,7 +7,7 @@
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.TodoComment
namespace
Microsoft.CodeAnalysis.TodoComment
s
{
/// <summary>
/// Serialization typed used to pass information to/from OOP and VS.
...
...
src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_TodoComments.cs
浏览文件 @
0a1fb50b
...
...
@@ -15,7 +15,7 @@
namespace
Microsoft.CodeAnalysis.Remote
{
// root level service for all Roslyn services
internal
partial
class
CodeAnalysisService
:
IRemoteTodoCommentService
internal
partial
class
CodeAnalysisService
:
IRemoteTodoComment
s
Service
{
/// <summary>
/// This is top level entry point for TodoComments service from client (VS).
...
...
src/Workspaces/Remote/ServiceHub/Services/TodoComment/DescriptorsInfo.cs
已删除
100644 → 0
浏览文件 @
f8cdc451
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using
System.Collections.Immutable
;
using
Microsoft.CodeAnalysis.TodoComments
;
namespace
Microsoft.CodeAnalysis.Remote.Services.TodoComment
{
internal
class
DescriptorInfo
{
public
readonly
string
OptionText
;
public
readonly
ImmutableArray
<
TodoCommentDescriptor
>
Descriptors
;
public
DescriptorInfo
(
string
optionText
,
ImmutableArray
<
TodoCommentDescriptor
>
descriptors
)
{
this
.
OptionText
=
optionText
;
this
.
Descriptors
=
descriptors
;
}
}
}
src/Workspaces/Remote/ServiceHub/Services/TodoComment/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
已删除
100644 → 0
浏览文件 @
f8cdc451
// Licensed to the .NET Foundation under one or more agreements.
// 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
System.IO
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.TodoComments
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Remote
{
internal
partial
class
RemoteTodoCommentIncrementalAnalyzer
{
private
const
string
SerializationFormat
=
"1"
;
private
async
Task
<
PersistedTodoCommentInfo
?>
TryReadExistingCommentInfoAsync
(
IPersistentStorage
storage
,
Document
document
,
CancellationToken
cancellationToken
)
{
using
var
stream
=
await
storage
.
ReadStreamAsync
(
document
,
DataKey
,
cancellationToken
).
ConfigureAwait
(
false
);
using
var
reader
=
ObjectReader
.
TryGetReader
(
stream
,
cancellationToken
:
cancellationToken
);
return
TryReadPersistedInfo
(
reader
);
}
private
async
Task
PersistTodoCommentsAsync
(
IPersistentStorage
storage
,
Document
document
,
PersistedTodoCommentInfo
info
,
CancellationToken
cancellationToken
)
{
using
var
memoryStream
=
new
MemoryStream
();
using
var
writer
=
new
ObjectWriter
(
memoryStream
);
writer
.
WriteString
(
SerializationFormat
);
info
.
Version
.
WriteTo
(
writer
);
writer
.
WriteString
(
info
.
OptionText
);
writer
.
WriteInt32
(
info
.
TodoComments
.
Length
);
foreach
(
var
comment
in
info
.
TodoComments
)
comment
.
WriteTo
(
writer
);
memoryStream
.
Position
=
0
;
await
storage
.
WriteStreamAsync
(
document
,
DataKey
,
memoryStream
,
cancellationToken
).
ConfigureAwait
(
false
);
}
private
static
PersistedTodoCommentInfo
?
TryReadPersistedInfo
(
ObjectReader
reader
)
{
if
(
reader
==
null
)
return
null
;
try
{
var
serializationFormat
=
reader
.
ReadString
();
if
(
serializationFormat
!=
SerializationFormat
)
return
null
;
var
version
=
VersionStamp
.
ReadFrom
(
reader
);
var
optionText
=
reader
.
ReadString
();
var
count
=
reader
.
ReadInt32
();
using
var
_
=
ArrayBuilder
<
TodoCommentInfo
>.
GetInstance
(
out
var
comments
);
for
(
int
i
=
0
;
i
<
count
;
i
++)
comments
.
Add
(
TodoCommentInfo
.
ReadFrom
(
reader
));
return
new
PersistedTodoCommentInfo
{
Version
=
version
,
OptionText
=
optionText
,
TodoComments
=
comments
.
ToImmutable
(),
};
}
catch
{
}
return
null
;
}
private
class
PersistedTodoCommentInfo
{
public
VersionStamp
Version
;
public
string
?
OptionText
;
public
ImmutableArray
<
TodoCommentInfo
>
TodoComments
;
}
}
}
src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentIncrementalAnalyzer_Serialization.cs
0 → 100644
浏览文件 @
0a1fb50b
//// Licensed to the .NET Foundation under one or more agreements.
//// 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 System.IO;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.CodeAnalysis.Host;
//using Microsoft.CodeAnalysis.PooledObjects;
//using Microsoft.CodeAnalysis.TodoComments;
//using Roslyn.Utilities;
//namespace Microsoft.CodeAnalysis.Remote
//{
// internal partial class RemoteTodoCommentIncrementalAnalyzer
// {
// private const string SerializationFormat = "1";
// private async Task<PersistedTodoCommentInfo?> TryReadExistingCommentInfoAsync(
// IPersistentStorage storage, Document document, CancellationToken cancellationToken)
// {
// using var stream = await storage.ReadStreamAsync(document, DataKey, cancellationToken).ConfigureAwait(false);
// using var reader = ObjectReader.TryGetReader(stream, cancellationToken: cancellationToken);
// return TryReadPersistedInfo(reader);
// }
// private async Task PersistTodoCommentsAsync(
// IPersistentStorage storage,
// Document document,
// PersistedTodoCommentInfo info,
// CancellationToken cancellationToken)
// {
// using var memoryStream = new MemoryStream();
// using var writer = new ObjectWriter(memoryStream);
// writer.WriteString(SerializationFormat);
// info.Version.WriteTo(writer);
// writer.WriteString(info.OptionText);
// writer.WriteInt32(info.TodoComments.Length);
// foreach (var comment in info.TodoComments)
// comment.WriteTo(writer);
// memoryStream.Position = 0;
// await storage.WriteStreamAsync(
// document, DataKey, memoryStream, cancellationToken).ConfigureAwait(false);
// }
// private static PersistedTodoCommentInfo? TryReadPersistedInfo(ObjectReader reader)
// {
// if (reader == null)
// return null;
// try
// {
// var serializationFormat = reader.ReadString();
// if (serializationFormat != SerializationFormat)
// return null;
// var version = VersionStamp.ReadFrom(reader);
// var optionText = reader.ReadString();
// var count = reader.ReadInt32();
// using var _ = ArrayBuilder<TodoCommentInfo>.GetInstance(out var comments);
// for (int i = 0; i < count; i++)
// comments.Add(TodoCommentInfo.ReadFrom(reader));
// return new PersistedTodoCommentInfo
// {
// Version = version,
// OptionText = optionText,
// TodoComments = comments.ToImmutable(),
// };
// }
// catch
// {
// }
// return null;
// }
// private class PersistedTodoCommentInfo
// {
// public VersionStamp Version;
// public string? OptionText;
// public ImmutableArray<TodoCommentInfo> TodoComments;
// }
// }
//}
src/Workspaces/Remote/ServiceHub/Services/TodoComment
/RemoteTodoComment
IncrementalAnalyzer.cs
→
src/Workspaces/Remote/ServiceHub/Services/TodoComment
s/RemoteTodoComments
IncrementalAnalyzer.cs
浏览文件 @
0a1fb50b
...
...
@@ -5,29 +5,22 @@
#
nullable
enable
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Immutable
;
using
System.IO
;
using
System.Security.Cryptography
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
System.Windows.Media.TextFormatting
;
using
Microsoft.CodeAnalysis
;
using
Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
;
using
Microsoft.CodeAnalysis.Host
;
using
Microsoft.CodeAnalysis.Options
;
using
Microsoft.CodeAnalysis.PooledObjects
;
using
Microsoft.CodeAnalysis.ProjectTelemetry
;
using
Microsoft.CodeAnalysis.Remote.Services.TodoComment
;
using
Microsoft.CodeAnalysis.Shared.Extensions
;
using
Microsoft.CodeAnalysis.SolutionCrawler
;
using
Microsoft.CodeAnalysis.Text
;
using
Microsoft.CodeAnalysis.TodoComments
;
using
Roslyn.Utilities
;
namespace
Microsoft.CodeAnalysis.Remote
{
internal
partial
class
RemoteTodoCommentIncrementalAnalyzer
:
IncrementalAnalyzerBase
internal
partial
class
RemoteTodoComment
s
IncrementalAnalyzer
:
IncrementalAnalyzerBase
{
private
const
string
DataKey
=
"TodoComment"
;
...
...
@@ -39,9 +32,9 @@ internal partial class RemoteTodoCommentIncrementalAnalyzer : IncrementalAnalyze
private
readonly
IPersistentStorageService
_storageService
;
private
readonly
object
_gate
=
new
object
();
private
DescriptorInfo
?
_lastDescriptorInfo
;
private
ParsedTodoCommentDescriptors
?
_lastDescriptorInfo
;
public
RemoteTodoCommentIncrementalAnalyzer
(
Workspace
workspace
,
RemoteEndPoint
endPoint
)
public
RemoteTodoComment
s
IncrementalAnalyzer
(
Workspace
workspace
,
RemoteEndPoint
endPoint
)
{
_endPoint
=
endPoint
;
_storageService
=
workspace
.
Services
.
GetRequiredService
<
IPersistentStorageService
>();
...
...
@@ -50,16 +43,16 @@ public RemoteTodoCommentIncrementalAnalyzer(Workspace workspace, RemoteEndPoint
public
override
bool
NeedsReanalysisOnOptionChanged
(
object
sender
,
OptionChangedEventArgs
e
)
=>
e
.
Option
==
TodoCommentOptions
.
TokenList
;
private
DescriptorInfo
GetDescriptorInfo
(
Document
document
)
private
ParsedTodoCommentDescriptors
GetParsedTodoCommentDescriptors
(
Document
document
)
{
var
optionText
=
document
.
Project
.
Solution
.
Options
.
GetOption
(
TodoCommentOptions
.
TokenList
);
lock
(
_gate
)
{
if
(
_lastDescriptorInfo
==
null
||
_lastDescriptorInfo
.
OptionText
!=
optionText
)
_lastDescriptorInfo
=
new
DescriptorInfo
(
optionText
,
TodoCommentDescriptor
.
Parse
(
optionText
)
);
if
(
_lastDescriptorInfo
==
null
||
_lastDescriptorInfo
.
Value
.
OptionText
!=
optionText
)
_lastDescriptorInfo
=
ParsedTodoCommentDescriptors
.
Parse
(
optionText
);
return
_lastDescriptorInfo
;
return
_lastDescriptorInfo
.
Value
;
}
}
...
...
@@ -69,20 +62,20 @@ public override async Task AnalyzeSyntaxAsync(Document document, InvocationReaso
if
(
todoCommentService
==
null
)
return
;
using
var
storage
=
_storageService
.
GetStorage
(
document
.
Project
.
Solution
);
//
using var storage = _storageService.GetStorage(document.Project.Solution);
var
version
=
await
document
.
GetSyntaxVersionAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
var
descriptorInfo
=
Get
DescriptorInfo
(
document
);
//
var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
var
descriptorInfo
=
Get
ParsedTodoCommentDescriptors
(
document
);
var
persistedInfo
=
await
TryReadExistingCommentInfoAsync
(
storage
,
document
,
cancellationToken
).
ConfigureAwait
(
false
);
if
(
persistedInfo
!=
null
&&
persistedInfo
.
Version
==
version
&&
persistedInfo
.
OptionText
==
descriptorInfo
.
OptionText
)
{
// Our info for this file is up to date.
return
;
}
//
var persistedInfo = await TryReadExistingCommentInfoAsync(
//
storage, document, cancellationToken).ConfigureAwait(false);
//
if (persistedInfo != null &&
//
persistedInfo.Version == version &&
//
persistedInfo.OptionText == descriptorInfo.OptionText)
//
{
//
// Our info for this file is up to date.
//
return;
//
}
// We're out of date. Recompute this info.
var
todoComments
=
await
todoCommentService
.
GetTodoCommentsAsync
(
...
...
@@ -99,16 +92,16 @@ public override async Task AnalyzeSyntaxAsync(Document document, InvocationReaso
new
object
[]
{
converted
},
cancellationToken
).
ConfigureAwait
(
false
);
persistedInfo
=
new
PersistedTodoCommentInfo
{
Version
=
version
,
OptionText
=
descriptorInfo
.
OptionText
,
TodoComments
=
converted
.
ToImmutable
(),
};
//
persistedInfo = new PersistedTodoCommentInfo
//
{
//
Version = version,
//
OptionText = descriptorInfo.OptionText,
//
TodoComments = converted.ToImmutable(),
//
};
// now that we've informed VS, save this information for the future.
await
PersistTodoCommentsAsync
(
storage
,
document
,
persistedInfo
,
cancellationToken
).
ConfigureAwait
(
false
);
//
//
now that we've informed VS, save this information for the future.
//
await PersistTodoCommentsAsync(
//
storage, document, persistedInfo, cancellationToken).ConfigureAwait(false);
}
private
async
Task
ConvertAsync
(
...
...
src/Workspaces/Remote/ServiceHub/Services/TodoComment
/RemoteTodoComment
IncrementalAnalyzerProvider.cs
→
src/Workspaces/Remote/ServiceHub/Services/TodoComment
s/RemoteTodoComments
IncrementalAnalyzerProvider.cs
浏览文件 @
0a1fb50b
...
...
@@ -13,16 +13,16 @@ namespace Microsoft.CodeAnalysis.Remote
/// and then calls into OOP to tell it to start analyzing the solution. At that point we'll get
/// created and added to the solution crawler.
/// </remarks>
internal
class
RemoteTodoCommentIncrementalAnalyzerProvider
:
IIncrementalAnalyzerProvider
internal
class
RemoteTodoComment
s
IncrementalAnalyzerProvider
:
IIncrementalAnalyzerProvider
{
private
readonly
RemoteEndPoint
_endPoint
;
public
RemoteTodoCommentIncrementalAnalyzerProvider
(
RemoteEndPoint
endPoint
)
public
RemoteTodoComment
s
IncrementalAnalyzerProvider
(
RemoteEndPoint
endPoint
)
{
_endPoint
=
endPoint
;
}
public
IIncrementalAnalyzer
CreateIncrementalAnalyzer
(
Workspace
workspace
)
=>
new
RemoteTodoComment
IncrementalAnalyzer
(
_endPoint
);
=>
new
RemoteTodoComment
sIncrementalAnalyzer
(
workspace
,
_endPoint
);
}
}
src/Workspaces/Remote/ServiceHub/Services/TodoComment/RemoteTodoCommentsService.cs
→
src/Workspaces/Remote/ServiceHub/Services/TodoComment
s
/RemoteTodoCommentsService.cs
浏览文件 @
0a1fb50b
...
...
@@ -10,12 +10,13 @@
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.ProjectTelemetry
;
using
Microsoft.CodeAnalysis.SolutionCrawler
;
using
Microsoft.CodeAnalysis.TodoComments
;
namespace
Microsoft.CodeAnalysis.Remote
{
internal
partial
class
RemoteTodoComment
Service
:
ServiceBase
,
IRemoteTodoComment
Service
internal
partial
class
RemoteTodoComment
sService
:
ServiceBase
,
IRemoteTodoComments
Service
{
public
RemoteTodoCommentService
(
public
RemoteTodoComment
s
Service
(
Stream
stream
,
IServiceProvider
serviceProvider
)
:
base
(
serviceProvider
,
stream
)
{
...
...
@@ -29,12 +30,12 @@ public Task ComputeTodoCommentsAsync(CancellationToken cancellation)
var
workspace
=
SolutionService
.
PrimaryWorkspace
;
var
endpoint
=
this
.
EndPoint
;
var
registrationService
=
workspace
.
Services
.
GetRequiredService
<
ISolutionCrawlerRegistrationService
>();
var
analyzerProvider
=
new
RemoteTodoCommentIncrementalAnalyzerProvider
(
endpoint
);
var
analyzerProvider
=
new
RemoteTodoComment
s
IncrementalAnalyzerProvider
(
endpoint
);
registrationService
.
AddAnalyzerProvider
(
analyzerProvider
,
new
IncrementalAnalyzerProviderMetadata
(
nameof
(
RemoteTodoCommentIncrementalAnalyzerProvider
),
nameof
(
RemoteTodoComment
s
IncrementalAnalyzerProvider
),
highPriorityForActiveFile
:
false
,
workspaceKinds
:
WorkspaceKind
.
RemoteWorkspace
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录