提交 680a600b 编写于 作者: H Heejae Chang

run todo comments on remote host for closed files.

上级 d5b1768c
......@@ -153,7 +153,6 @@
<Compile Include="SplitStringLiteral\SplitStringLiteralCommandHandler.StringSplitter.cs" />
<Compile Include="SplitStringLiteral\SplitStringLiteralOptions.cs" />
<Compile Include="TextStructureNavigation\TextStructureNavigatorProvider.cs" />
<Compile Include="TodoComment\CSharpTodoCommentIncrementalAnalyzerProvider.cs" />
<Compile Include="UseAutoProperty\UseAutoPropertyAnalyzer.cs" />
<Compile Include="UseAutoProperty\UseAutoPropertyCodeFixProvider.cs" />
</ItemGroup>
......
......@@ -614,8 +614,6 @@
<Compile Include="Implementation\TextStructureNavigation\AbstractTextStructureNavigatorProvider.cs" />
<Compile Include="Implementation\TextStructureNavigation\AbstractTextStructureNavigatorProvider.TextStructureNavigator.cs" />
<Compile Include="Implementation\TodoComment\AbstractTodoCommentIncrementalAnalyzer.cs" />
<Compile Include="Implementation\TodoComment\AbstractTodoCommentService.cs" />
<Compile Include="Implementation\TodoComment\ITodoCommentService.cs" />
<Compile Include="Implementation\TodoComment\TodoCommentIncrementalAnalyzerProvider.cs" />
<Compile Include="Implementation\TodoComment\TodoCommentOptions.cs" />
<Compile Include="Implementation\TodoComment\TodoCommentState.cs" />
......
......@@ -8,9 +8,11 @@
using Microsoft.CodeAnalysis.Common;
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.TodoComments;
using Microsoft.CodeAnalysis.Versions;
using Roslyn.Utilities;
......@@ -70,14 +72,8 @@ public async Task AnalyzeSyntaxAsync(Document document, InvocationReasons reason
}
}
var service = document.GetLanguageService<ITodoCommentService>();
if (service == null)
{
return;
}
var tokens = _todoCommentTokens.GetTokens(document, cancellationToken);
var comments = await service.GetTodoCommentsAsync(document, tokens, cancellationToken).ConfigureAwait(false);
var comments = await GetTodoCommentsAsync(document, tokens, cancellationToken).ConfigureAwait(false);
var items = await CreateItemsAsync(document, comments, cancellationToken).ConfigureAwait(false);
var data = new Data(textVersion, syntaxVersion, items);
......@@ -91,9 +87,31 @@ public async Task AnalyzeSyntaxAsync(Document document, InvocationReasons reason
}
}
private async Task<IList<TodoComment>> GetTodoCommentsAsync(Document document, ImmutableArray<TodoCommentDescriptor> tokens, CancellationToken cancellationToken)
{
var client = await _workspace.GetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false);
if (client != null && !document.IsOpen())
{
// run todo scanner on remote host
return await client.RunCodeAnalysisServiceOnRemoteHostAsync<IList<TodoComment>>(
document.Project.Solution, nameof(IRemoteTodoCommentService.GetTodoCommentsAsync),
new object[] { document.Id, tokens }, cancellationToken).ConfigureAwait(false);
}
// No remote host support, use inproc service
var service = document.GetLanguageService<ITodoCommentService>();
if (service == null)
{
// no inproc support
return SpecializedCollections.EmptyList<TodoComment>();
}
return await service.GetTodoCommentsAsync(document, tokens, cancellationToken).ConfigureAwait(false);
}
private async Task<ImmutableArray<TodoItem>> CreateItemsAsync(Document document, IList<TodoComment> comments, CancellationToken cancellationToken)
{
var items = ArrayBuilder<TodoItem>.GetInstance();
var items = ImmutableArray.CreateBuilder<TodoItem>();
if (comments != null)
{
var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
......@@ -105,7 +123,7 @@ private async Task<ImmutableArray<TodoItem>> CreateItemsAsync(Document document,
}
}
return items.ToImmutableAndFree();
return items.ToImmutable();
}
private TodoItem CreateItem(Document document, SourceText text, SyntaxTree tree, TodoComment comment)
......
......@@ -5,8 +5,7 @@
using System.ComponentModel.Composition;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.TodoComments;
namespace Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
{
......
......@@ -160,7 +160,6 @@
<Compile Include="RenameTracking\BasicRenameTrackingLanguageHeuristicsService.vb" />
<Compile Include="RenameTracking\RenameTrackingCodeFixProvider.vb" />
<Compile Include="TextStructureNavigation\TextStructureNavigatorProvider.vb" />
<Compile Include="TodoComment\BasicTodoCommentIncrementalAnalyzerProvider.vb" />
<Compile Include="UseAutoProperty\UseAutoPropertyAnalyzer.vb" />
<Compile Include="UseAutoProperty\UseAutoPropertyCodeFixProvider.vb" />
<Compile Include="UseAutoProperty\Utilities.vb" />
......
......@@ -79,6 +79,7 @@
<Compile Include="RemoveUnnecessaryImports\CSharpRemoveUnnecessaryImportsService.cs" />
<Compile Include="RemoveUnnecessaryImports\CSharpUnnecessaryImportsService.cs" />
<Compile Include="Structure\Providers\InitializerExpressionStructureProvider.cs" />
<Compile Include="TodoComments\CSharpTodoCommentIncrementalAnalyzerProvider.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionDiagnosticAnalyzer.cs" />
<Compile Include="UseExpressionBody\Accessors\UseExpressionBodyForAccessorsCodeFixProvider.cs" />
......
......@@ -4,13 +4,12 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.Editor.Implementation.TodoComments;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.TodoComments;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.CSharp.TodoComments
namespace Microsoft.CodeAnalysis.CSharp.TodoComments
{
[ExportLanguageService(typeof(ITodoCommentService), LanguageNames.CSharp), Shared]
internal class CSharpTodoCommentService : AbstractTodoCommentService
......
......@@ -157,6 +157,9 @@
<Compile Include="Remote\RemoteArguments.cs" />
<Compile Include="Structure\BlockStructureOptions.cs" />
<Compile Include="AddImport\CodeActions\SymbolReference.SymbolReferenceCodeAction.cs" />
<Compile Include="TodoComments\AbstractTodoCommentService.cs" />
<Compile Include="TodoComments\IRemoteTodoCommentService.cs" />
<Compile Include="TodoComments\ITodoCommentService.cs" />
<Compile Include="UseCollectionInitializer\AbstractUseCollectionInitializerCodeFixProvider.cs" />
<Compile Include="UseCollectionInitializer\AbstractUseCollectionInitializerDiagnosticAnalyzer.cs" />
<Compile Include="UseCoalesceExpression\AbstractUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs" />
......
......@@ -7,7 +7,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
namespace Microsoft.CodeAnalysis.TodoComments
{
internal abstract class AbstractTodoCommentService : ITodoCommentService
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.TodoComments
{
/// <summary>
/// interface exist to strongly type todo comment remote service
/// </summary>
internal interface IRemoteTodoCommentService
{
Task<IList<TodoComment>> GetTodoCommentsAsync(DocumentId documentId, ImmutableArray<TodoCommentDescriptor> commentDescriptors);
}
}
......@@ -6,7 +6,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Editor
namespace Microsoft.CodeAnalysis.TodoComments
{
/// <summary>
/// Description of a TODO comment type to find in a user's comments.
......
......@@ -418,6 +418,7 @@
<Compile Include="SolutionCrawler\VisualBasicDocumentDifferenceService.vb" />
<Compile Include="Structure\Providers\SyncLockBlockStructureProvider.vb" />
<Compile Include="Structure\Providers\TryBlockStructureProvider.vb" />
<Compile Include="TodoComments\BasicTodoCommentIncrementalAnalyzerProvider.vb" />
<Compile Include="UseCollectionInitializer\VisualBasicUseCollectionInitializerCodeFixProvider.vb" />
<Compile Include="UseCollectionInitializer\VisualBasicUseCollectionInitializerDiagnosticAnalyzer.vb" />
<Compile Include="UseCoalesceExpression\VisualBasicUseCoalesceExpressionForNullableDiagnosticAnalyzer.vb" />
......
......@@ -3,10 +3,10 @@
Imports System.Collections.Immutable
Imports System.Composition
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Editor.Implementation.TodoComments
Imports Microsoft.CodeAnalysis.Host.Mef
Imports Microsoft.CodeAnalysis.TodoComments
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.TodoComments
Namespace Microsoft.CodeAnalysis.VisualBasic.TodoComments
<ExportLanguageService(GetType(ITodoCommentService), LanguageNames.VisualBasic), [Shared]>
Friend Class VisualBasicTodoCommentService
Inherits AbstractTodoCommentService
......
......@@ -79,6 +79,9 @@
<Compile Include="..\..\..\Workspaces\Remote\ServiceHub\Shared\RoslynJsonConverter.cs">
<Link>Shared\RoslynJsonConverter.cs</Link>
</Compile>
<Compile Include="..\..\..\Workspaces\Remote\ServiceHub\Shared\RoslynJsonConverter.RoslynOnly.cs">
<Link>Shared\RoslynJsonConverter.RoslynOnly.cs</Link>
</Compile>
<Compile Include="..\..\..\Workspaces\Remote\ServiceHub\Shared\RoslynJsonConverter.SolutionIdConverters.cs">
<Link>Shared\RoslynJsonConverter.SolutionIdConverters.cs</Link>
</Compile>
......
......@@ -3,12 +3,14 @@
extern alias hub;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.TodoComments;
using Newtonsoft.Json;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -82,6 +84,38 @@ public void TestSymbolKey()
VerifyJsonSerialization(new SymbolKey("TEST"));
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestTodoCommentDescriptor()
{
VerifyJsonSerialization(new TodoCommentDescriptor("Test", 0));
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestTodoComment()
{
VerifyJsonSerialization(new TodoComment(new TodoCommentDescriptor("Test", 1), "Message", 10));
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestTodoCommentDescriptorImmutableArray()
{
VerifyJsonSerialization(ImmutableArray.Create(new TodoCommentDescriptor("Test", 0), new TodoCommentDescriptor("Test1", 1)), (x, y) =>
{
return x.SequenceEqual(y) ? 0 : 1;
});
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestTodoCommentList()
{
VerifyJsonSerialization(new[] {
new TodoComment(new TodoCommentDescriptor("Test1", 1), "Message1", 10),
new TodoComment(new TodoCommentDescriptor("Test2", 2), "Message2", 20)}.ToList(), (x, y) =>
{
return x.SequenceEqual(y) ? 0 : 1;
});
}
private static void VerifyJsonSerialization<T>(T value, Comparison<T> equality = null)
{
var serializer = new JsonSerializer();
......
......@@ -364,5 +364,6 @@ internal enum FunctionId
FileTextLoader_FileLengthThresholdExceeded,
RemoteHost_Connect,
RemoteHost_Disconnect,
CodeAnalysisService_GetTodoCommentsAsync,
}
}
......@@ -56,6 +56,7 @@
<ItemGroup>
<Compile Include="CodeLens\CodeLensArguments.cs" />
<Compile Include="Services\CodeAnalysisService_CodeLens.cs" />
<Compile Include="Services\CodeAnalysisService_TodoComments.cs" />
<Compile Include="Services\CodeAnalysisService_FindReferences.cs" />
<Compile Include="Services\RemoteSymbolSearchUpdateEngine.cs" />
<Compile Include="Services\CodeAnalysisService_NavigateTo.cs" />
......@@ -63,6 +64,7 @@
<Compile Include="Services\CodeAnalysisService.cs" />
<Compile Include="Services\CodeAnalysisService_Diagnostics.cs" />
<Compile Include="Services\RemoteHostService.cs" />
<Compile Include="Shared\RoslynJsonConverter.RoslynOnly.cs" />
<Compile Include="Shared\ServiceHubServiceBase.cs" />
<Compile Include="Services\SnapshotService.cs" />
<Compile Include="Shared\Extensions.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.TodoComments;
using Roslyn.Utilities;
using RoslynLogger = Microsoft.CodeAnalysis.Internal.Log.Logger;
namespace Microsoft.CodeAnalysis.Remote
{
// root level service for all Roslyn services
internal partial class CodeAnalysisService : IRemoteTodoCommentService
{
/// <summary>
/// This is top level entry point for TodoComments service from client (VS).
///
/// This will be called by ServiceHub/JsonRpc framework
/// </summary>
public async Task<IList<TodoComment>> GetTodoCommentsAsync(DocumentId documentId, ImmutableArray<TodoCommentDescriptor> tokens)
{
using (RoslynLogger.LogBlock(FunctionId.CodeAnalysisService_GetTodoCommentsAsync, documentId.ProjectId.DebugName, CancellationToken))
{
try
{
var solution = await GetSolutionAsync().ConfigureAwait(false);
var document = solution.GetDocument(documentId);
var service = document.GetLanguageService<ITodoCommentService>();
if (service != null)
{
// todo comment service supported
return await service.GetTodoCommentsAsync(document, tokens, CancellationToken).ConfigureAwait(false);
}
}
catch (IOException)
{
// stream to send over result has closed before we
// had chance to check cancellation
}
catch (OperationCanceledException)
{
// rpc connection has closed.
// this can happen if client side cancelled the
// operation
}
return SpecializedCollections.EmptyList<TodoComment>();
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.TodoComments;
using Newtonsoft.Json;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Remote
{
internal partial class AggregateJsonConverter : JsonConverter
{
partial void AppendRoslynSpecificJsonConverters(ImmutableDictionary<Type, JsonConverter>.Builder builder)
{
builder.Add(typeof(TodoCommentDescriptor), new TodoCommentDescriptorJsonConverter());
builder.Add(typeof(TodoComment), new TodoCommentJsonConverter());
}
private class TodoCommentDescriptorJsonConverter : BaseJsonConverter
{
public override bool CanConvert(Type objectType) => typeof(TodoCommentDescriptor) == objectType;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject);
// all integer is long
var text = ReadProperty<string>(reader);
var priority = ReadProperty<long>(reader);
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject);
return new TodoCommentDescriptor(text, (int)priority);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var descriptor = (TodoCommentDescriptor)value;
writer.WriteStartObject();
writer.WritePropertyName("text");
writer.WriteValue(descriptor.Text);
writer.WritePropertyName("priority");
writer.WriteValue(descriptor.Priority);
writer.WriteEndObject();
}
}
private class TodoCommentJsonConverter : BaseJsonConverter
{
public override bool CanConvert(Type objectType) => typeof(TodoComment) == objectType;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject);
// all integer is long
var descriptor = ReadProperty<TodoCommentDescriptor>(serializer, reader);
var message = ReadProperty<string>(reader);
var position = ReadProperty<long>(reader);
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject);
return new TodoComment(descriptor, message, (int)position);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var todoComment = (TodoComment)value;
writer.WriteStartObject();
writer.WritePropertyName("descriptor");
serializer.Serialize(writer, todoComment.Descriptor);
writer.WritePropertyName("message");
writer.WriteValue(todoComment.Message);
writer.WritePropertyName("position");
writer.WriteValue(todoComment.Position);
writer.WriteEndObject();
}
}
}
}
......@@ -34,6 +34,11 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
_map[value.GetType()].WriteJson(writer, value, serializer);
}
// this type is shared by multiple teams such as Razor, LUT and etc which have either separated/shared/shim repo
// so some types might not available to those context. this partial method let us add Roslyn specific types
// without breaking them
partial void AppendRoslynSpecificJsonConverters(ImmutableDictionary<Type, JsonConverter>.Builder builder);
private ImmutableDictionary<Type, JsonConverter> CreateConverterMap()
{
var builder = ImmutableDictionary.CreateBuilder<Type, JsonConverter>();
......@@ -45,6 +50,8 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
builder.Add(typeof(TextSpan), new TextSpanJsonConverter());
builder.Add(typeof(SymbolKey), new SymbolKeyJsonConverter());
AppendRoslynSpecificJsonConverters(builder);
return builder.ToImmutable();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册