提交 174829f7 编写于 作者: H Heejae Chang

get rid of Serializable documentid/projectid/textspan

上级 fc50ddac
......@@ -20,7 +20,7 @@ internal abstract partial class AbstractNavigateToSearchService
{
var serializableResults = await session.InvokeAsync<SerializableNavigateToSearchResult[]>(
nameof(IRemoteNavigateToSearchService.SearchDocumentAsync),
SerializableDocumentId.Dehydrate(document),
document.Id,
searchPattern).ConfigureAwait(false);
return serializableResults.Select(r => r.Rehydrate(solution)).ToImmutableArray();
......@@ -37,7 +37,7 @@ internal abstract partial class AbstractNavigateToSearchService
{
var serializableResults = await session.InvokeAsync<SerializableNavigateToSearchResult[]>(
nameof(IRemoteNavigateToSearchService.SearchProjectAsync),
SerializableProjectId.Dehydrate(project.Id),
project.Id,
searchPattern).ConfigureAwait(false);
return serializableResults.Select(r => r.Rehydrate(solution)).ToImmutableArray();
......
......@@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.NavigateTo
{
internal interface IRemoteNavigateToSearchService
{
Task<SerializableNavigateToSearchResult[]> SearchDocumentAsync(SerializableDocumentId documentId, string searchPattern);
Task<SerializableNavigateToSearchResult[]> SearchProjectAsync(SerializableProjectId projectId, string searchPattern);
Task<SerializableNavigateToSearchResult[]> SearchDocumentAsync(DocumentId documentId, string searchPattern);
Task<SerializableNavigateToSearchResult[]> SearchProjectAsync(ProjectId projectId, string searchPattern);
}
}
......@@ -39,7 +39,7 @@ internal class SerializableNavigateToSearchResult
public NavigateToMatchKind MatchKind;
public bool IsCaseSensitive;
public string Name;
public SerializableTextSpan[] NameMatchSpans;
public TextSpan[] NameMatchSpans;
public string SecondarySort;
public string Summary;
......@@ -54,7 +54,7 @@ internal static SerializableNavigateToSearchResult Dehydrate(INavigateToSearchRe
MatchKind = result.MatchKind,
IsCaseSensitive = result.IsCaseSensitive,
Name = result.Name,
NameMatchSpans = result.NameMatchSpans.Select(SerializableTextSpan.Dehydrate).ToArray(),
NameMatchSpans = result.NameMatchSpans.ToArray(),
SecondarySort = result.SecondarySort,
Summary = result.Summary,
NavigableItem = SerializableNavigableItem.Dehydrate(result.NavigableItem)
......@@ -65,7 +65,7 @@ internal INavigateToSearchResult Rehydrate(Solution solution)
{
return new NavigateToSearchResult(
AdditionalInformation, Kind, MatchKind, IsCaseSensitive,
Name, NameMatchSpans.Select(s => s.Rehydrate()).ToImmutableArray(),
Name, NameMatchSpans.ToImmutableArray(),
SecondarySort, Summary, NavigableItem.Rehydrate(solution));
}
......@@ -83,7 +83,7 @@ private class NavigateToSearchResult : INavigateToSearchResult
public INavigableItem NavigableItem { get; }
public NavigateToSearchResult(
string additionalInformation, string kind, NavigateToMatchKind matchKind,
string additionalInformation, string kind, NavigateToMatchKind matchKind,
bool isCaseSensitive, string name, ImmutableArray<TextSpan> nameMatchSpans,
string secondarySort, string summary, INavigableItem navigableItem)
{
......@@ -110,8 +110,8 @@ internal class SerializableNavigableItem
public bool IsImplicitlyDeclared;
public SerializableDocumentId Document;
public SerializableTextSpan SourceSpan;
public DocumentId Document;
public TextSpan SourceSpan;
SerializableNavigableItem[] ChildItems;
......@@ -123,8 +123,8 @@ public static SerializableNavigableItem Dehydrate(INavigableItem item)
DisplayTaggedParts = SerializableTaggedText.Dehydrate(item.DisplayTaggedParts),
DisplayFileLocation = item.DisplayFileLocation,
IsImplicitlyDeclared = item.IsImplicitlyDeclared,
Document = SerializableDocumentId.Dehydrate(item.Document),
SourceSpan = SerializableTextSpan.Dehydrate(item.SourceSpan),
Document = item.Document.Id,
SourceSpan = item.SourceSpan,
ChildItems = SerializableNavigableItem.Dehydrate(item.ChildItems)
};
}
......@@ -142,8 +142,8 @@ public INavigableItem Rehydrate(Solution solution)
return new NavigableItem(
Glyph, DisplayTaggedParts.Select(p => p.Rehydrate()).ToImmutableArray(),
DisplayFileLocation, IsImplicitlyDeclared,
solution.GetDocument(Document.Rehydrate()),
SourceSpan.Rehydrate(),
solution.GetDocument(Document),
SourceSpan,
childItems);
}
......
......@@ -8,6 +8,7 @@
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Text;
using Newtonsoft.Json;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -69,6 +70,12 @@ public void TestDiagnosticArguments()
});
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public void TestTextSpan()
{
VerifyJsonSerialization(new TextSpan(10, 5));
}
private static void VerifyJsonSerialization<T>(T value, Comparison<T> equality = null)
{
var serializer = new JsonSerializer();
......
......@@ -7,6 +7,6 @@ namespace Microsoft.CodeAnalysis.FindSymbols
{
internal interface IRemoteSymbolFinder
{
Task FindReferencesAsync(SerializableSymbolAndProjectId symbolAndProjectIdArg, SerializableDocumentId[] documentArgs);
Task FindReferencesAsync(SerializableSymbolAndProjectId symbolAndProjectIdArg, DocumentId[] documentArgs);
}
}
\ No newline at end of file
......@@ -38,15 +38,15 @@ private class ServerCallback
public Task OnCompletedAsync() => _progress.OnCompletedAsync();
public Task ReportProgressAsync(int current, int maximum) => _progress.ReportProgressAsync(current, maximum);
public Task OnFindInDocumentStartedAsync(SerializableDocumentId documentId)
public Task OnFindInDocumentStartedAsync(DocumentId documentId)
{
var document = _solution.GetDocument(documentId.Rehydrate());
var document = _solution.GetDocument(documentId);
return _progress.OnFindInDocumentStartedAsync(document);
}
public Task OnFindInDocumentCompletedAsync(SerializableDocumentId documentId)
public Task OnFindInDocumentCompletedAsync(DocumentId documentId)
{
var document = _solution.GetDocument(documentId.Rehydrate());
var document = _solution.GetDocument(documentId);
return _progress.OnFindInDocumentCompletedAsync(document);
}
......
......@@ -75,7 +75,7 @@ public static partial class SymbolFinder
await session.InvokeAsync(
nameof(IRemoteSymbolFinder.FindReferencesAsync),
SerializableSymbolAndProjectId.Dehydrate(symbolAndProjectId),
documents?.Select(SerializableDocumentId.Dehydrate).ToArray()).ConfigureAwait(false);
documents?.Select(d => d.Id).ToArray()).ConfigureAwait(false);
}
}
}
......
......@@ -12,88 +12,12 @@
namespace Microsoft.CodeAnalysis.Remote
{
#region Common Arguments
/// <summary>
/// Arguments to pass from client to server when performing operations
/// </summary>
internal class SerializableProjectId : IEquatable<SerializableProjectId>
{
public Guid Id;
public string DebugName;
public override int GetHashCode()
=> Hash.Combine(Id.GetHashCode(), DebugName.GetHashCode());
public override bool Equals(object obj)
=> Equals(obj as SerializableProjectId);
public bool Equals(SerializableProjectId obj)
=> obj != null && Id.Equals(obj.Id) && DebugName.Equals(obj.DebugName);
public static SerializableProjectId Dehydrate(ProjectId id)
{
return new SerializableProjectId { Id = id.Id, DebugName = id.DebugName };
}
public ProjectId Rehydrate()
{
return ProjectId.CreateFromSerialized(Id, DebugName);
}
}
internal class SerializableDocumentId
{
public SerializableProjectId ProjectId;
public Guid Id;
public string DebugName;
public static SerializableDocumentId Dehydrate(Document document)
{
return Dehydrate(document.Id);
}
public static SerializableDocumentId Dehydrate(DocumentId id)
{
return new SerializableDocumentId
{
ProjectId = SerializableProjectId.Dehydrate(id.ProjectId),
Id = id.Id,
DebugName = id.DebugName
};
}
public DocumentId Rehydrate()
{
return DocumentId.CreateFromSerialized(
ProjectId.Rehydrate(), Id, DebugName);
}
}
internal class SerializableTextSpan
{
public int Start;
public int Length;
public static SerializableTextSpan Dehydrate(TextSpan textSpan)
{
return new SerializableTextSpan { Start = textSpan.Start, Length = textSpan.Length };
}
public TextSpan Rehydrate()
{
return new TextSpan(Start, Length);
}
}
#endregion
#region FindReferences
internal class SerializableSymbolAndProjectId : IEquatable<SerializableSymbolAndProjectId>
{
public string SymbolKeyData;
public SerializableProjectId ProjectId;
public ProjectId ProjectId;
public override int GetHashCode()
=> Hash.Combine(SymbolKeyData, ProjectId.GetHashCode());
......@@ -118,14 +42,14 @@ public bool Equals(SerializableSymbolAndProjectId other)
return new SerializableSymbolAndProjectId
{
SymbolKeyData = symbolAndProjectId.Symbol.GetSymbolKey().ToString(),
ProjectId = SerializableProjectId.Dehydrate(symbolAndProjectId.ProjectId)
ProjectId = symbolAndProjectId.ProjectId
};
}
public async Task<SymbolAndProjectId> RehydrateAsync(
Solution solution, CancellationToken cancellationToken)
{
var projectId = ProjectId.Rehydrate();
var projectId = ProjectId;
var project = solution.GetProject(projectId);
var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var symbol = SymbolKey.Resolve(SymbolKeyData, compilation, cancellationToken: cancellationToken).GetAnySymbol();
......@@ -136,11 +60,11 @@ public bool Equals(SerializableSymbolAndProjectId other)
internal class SerializableReferenceLocation
{
public SerializableDocumentId Document { get; set; }
public DocumentId Document { get; set; }
public SerializableSymbolAndProjectId Alias { get; set; }
public SerializableTextSpan Location { get; set; }
public TextSpan Location { get; set; }
public bool IsImplicit { get; set; }
......@@ -153,9 +77,9 @@ internal class SerializableReferenceLocation
{
return new SerializableReferenceLocation
{
Document = SerializableDocumentId.Dehydrate(referenceLocation.Document),
Document = referenceLocation.Document.Id,
Alias = SerializableSymbolAndProjectId.Dehydrate(referenceLocation.Alias, referenceLocation.Document),
Location = SerializableTextSpan.Dehydrate(referenceLocation.Location.SourceSpan),
Location = referenceLocation.Location.SourceSpan,
IsImplicit = referenceLocation.IsImplicit,
IsWrittenTo = referenceLocation.IsWrittenTo,
CandidateReason = referenceLocation.CandidateReason
......@@ -165,13 +89,13 @@ internal class SerializableReferenceLocation
public async Task<ReferenceLocation> RehydrateAsync(
Solution solution, CancellationToken cancellationToken)
{
var document = solution.GetDocument(this.Document.Rehydrate());
var document = solution.GetDocument(this.Document);
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var aliasSymbol = await RehydrateAliasAsync(solution, cancellationToken).ConfigureAwait(false);
return new ReferenceLocation(
document,
aliasSymbol,
CodeAnalysis.Location.Create(syntaxTree, Location.Rehydrate()),
CodeAnalysis.Location.Create(syntaxTree, Location),
isImplicit: IsImplicit,
isWrittenTo: IsWrittenTo,
candidateReason: CandidateReason);
......
......@@ -13,6 +13,10 @@
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\..\Compilers\Core\Portable\CodeAnalysis.csproj">
<Project>{1ee8cad3-55f9-4d91-96b2-084641da9a6c}</Project>
<Name>CodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\Core\Portable\Workspaces.csproj">
<Project>{5F8D2414-064A-4B3A-9B42-8E2A04246BE5}</Project>
<Name>Workspaces</Name>
......@@ -36,6 +40,12 @@
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Compile Include="..\ServiceHub\Shared\RoslynJsonConverter.cs">
<Link>Shared\RoslynJsonConverter.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\RoslynJsonConverter.SolutionIdConverters.cs">
<Link>Shared\RoslynJsonConverter.SolutionIdConverters.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\ServiceHubServiceBase.cs">
<Link>Shared\ServiceHubServiceBase.cs</Link>
</Compile>
......
{
"dependencies": {
"StreamJsonRpc": "0.12.32-alpha-g90be50f449"
"StreamJsonRpc": "1.0.2-rc"
},
"frameworks": {
"net46": {}
......
......@@ -10,14 +10,13 @@ namespace Microsoft.CodeAnalysis.Remote
// root level service for all Roslyn services
internal partial class CodeAnalysisService : IRemoteSymbolFinder
{
public async Task FindReferencesAsync(SerializableSymbolAndProjectId symbolAndProjectIdArg, SerializableDocumentId[] documentArgs)
public async Task FindReferencesAsync(SerializableSymbolAndProjectId symbolAndProjectIdArg, DocumentId[] documentArgs)
{
var solution = await GetSolutionAsync().ConfigureAwait(false);
var symbolAndProjectId = await symbolAndProjectIdArg.RehydrateAsync(
solution, CancellationToken).ConfigureAwait(false);
var documents = documentArgs?.Select(a => a.Rehydrate())
.Select(solution.GetDocument)
var documents = documentArgs?.Select(solution.GetDocument)
.ToImmutableHashSet();
var progressCallback = new ProgressCallback(this);
......@@ -44,12 +43,10 @@ public Task ReportProgressAsync(int current, int maximum)
=> _service.Rpc.InvokeAsync(nameof(ReportProgressAsync), current, maximum);
public Task OnFindInDocumentStartedAsync(Document document)
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentStartedAsync),
SerializableDocumentId.Dehydrate(document));
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentStartedAsync), document.Id);
public Task OnFindInDocumentCompletedAsync(Document document)
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentCompletedAsync),
SerializableDocumentId.Dehydrate(document));
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentCompletedAsync), document.Id);
public Task OnDefinitionFoundAsync(SymbolAndProjectId definition)
=> _service.Rpc.InvokeAsync(nameof(OnDefinitionFoundAsync),
......
......@@ -10,11 +10,11 @@ namespace Microsoft.CodeAnalysis.Remote
internal partial class CodeAnalysisService : IRemoteNavigateToSearchService
{
public async Task<SerializableNavigateToSearchResult[]> SearchDocumentAsync(
SerializableDocumentId documentId, string searchPattern)
DocumentId documentId, string searchPattern)
{
var solution = await GetSolutionAsync().ConfigureAwait(false);
var project = solution.GetDocument(documentId.Rehydrate());
var project = solution.GetDocument(documentId);
var result = await AbstractNavigateToSearchService.SearchDocumentInCurrentProcessAsync(
project, searchPattern, CancellationToken).ConfigureAwait(false);
......@@ -22,11 +22,11 @@ internal partial class CodeAnalysisService : IRemoteNavigateToSearchService
}
public async Task<SerializableNavigateToSearchResult[]> SearchProjectAsync(
SerializableProjectId projectId, string searchPattern)
ProjectId projectId, string searchPattern)
{
var solution = await GetSolutionAsync().ConfigureAwait(false);
var project = solution.GetProject(projectId.Rehydrate());
var project = solution.GetProject(projectId);
var result = await AbstractNavigateToSearchService.SearchProjectInCurrentProcessAsync(
project, searchPattern, CancellationToken).ConfigureAwait(false);
......
......@@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Remote
{
internal partial class AggregateJsonConverter : JsonConverter
{
private abstract class WorkspaceIdJsonConverter : JsonConverter
private abstract class WorkspaceIdJsonConverter : BaseJsonConverter
{
protected (Guid, string) ReadFromJsonObject(JsonReader reader)
{
......@@ -45,26 +45,6 @@ protected static void WriteIdAndName(JsonWriter writer, Guid id, string debugNam
writer.WritePropertyName(nameof(debugName));
writer.WriteValue(debugName);
}
protected static T ReadProperty<T>(JsonSerializer serializer, JsonReader reader)
{
// read property
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.PropertyName);
Contract.ThrowIfFalse(reader.Read());
return serializer.Deserialize<T>(reader);
}
private static T ReadProperty<T>(JsonReader reader)
{
// read property
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.PropertyName);
Contract.ThrowIfFalse(reader.Read());
return (T)reader.Value;
}
}
private class SolutionIdJsonConverter : WorkspaceIdJsonConverter
......
......@@ -2,7 +2,9 @@
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Text;
using Newtonsoft.Json;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Remote
{
......@@ -40,10 +42,68 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
builder.Add(typeof(SolutionId), new SolutionIdJsonConverter());
builder.Add(typeof(ProjectId), new ProjectIdJsonConverter());
builder.Add(typeof(DocumentId), new DocumentIdJsonConverter());
builder.Add(typeof(TextSpan), new TextSpanJsonConverter());
return builder.ToImmutable();
}
private abstract class BaseJsonConverter : JsonConverter
{
protected static T ReadProperty<T>(JsonSerializer serializer, JsonReader reader)
{
// read property
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.PropertyName);
Contract.ThrowIfFalse(reader.Read());
return serializer.Deserialize<T>(reader);
}
protected static T ReadProperty<T>(JsonReader reader)
{
// read property
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.PropertyName);
Contract.ThrowIfFalse(reader.Read());
return (T)reader.Value;
}
}
private class TextSpanJsonConverter : BaseJsonConverter
{
public override bool CanConvert(Type objectType) => typeof(TextSpan) == objectType;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Contract.ThrowIfFalse(reader.TokenType == JsonToken.StartObject);
// all integer is long
var start = ReadProperty<long>(reader);
var length = ReadProperty<long>(reader);
Contract.ThrowIfFalse(reader.Read());
Contract.ThrowIfFalse(reader.TokenType == JsonToken.EndObject);
return new TextSpan((int)start, (int)length);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var span = (TextSpan)value;
writer.WriteStartObject();
writer.WritePropertyName("start");
writer.WriteValue(span.Start);
writer.WritePropertyName("length");
writer.WriteValue(span.Length);
writer.WriteEndObject();
}
}
private class ChecksumJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => typeof(Checksum) == objectType;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册