Serialize project state from VS to project.razor.json (dotnet/aspnetcore-tooling#1711)

Serialize project state to project.razor.json\n\nCommit migrated from fef50ba623
This commit is contained in:
Ryan Brandenburg 2020-03-31 11:07:08 -07:00 committed by GitHub
parent 926bbfa14b
commit 36c2448bd3
5 changed files with 446 additions and 2 deletions

View File

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Serialization;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.VisualStudio.LanguageServices.Razor.Serialization;
using Newtonsoft.Json;

View File

@ -7,9 +7,9 @@ using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Components;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;
using Microsoft.CodeAnalysis.Razor.Serialization;
using Microsoft.Extensions.CommandLineUtils;
using Microsoft.VisualStudio.LanguageServices.Razor.Serialization;
using Newtonsoft.Json;

View File

@ -23,7 +23,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Microsoft.VisualStudio.LanguageServices.Razor\Serialization\TagHelperDescriptorJsonConverter.cs">
<Compile Include="..\Microsoft.CodeAnalysis.Razor.Workspaces\Serialization\TagHelperDescriptorJsonConverter.cs">
<Link>Shared\TagHelperDescriptorJsonConverter.cs</Link>
</Compile>
<Compile Include="..\Microsoft.VisualStudio.LanguageServices.Razor\Serialization\RazorDiagnosticJsonConverter.cs">

View File

@ -12,4 +12,5 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Microsoft.CodeAnalysis.Razor.Workspaces.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServerClient.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

View File

@ -0,0 +1,442 @@
// Copyright (c) .NET Foundation. 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 Microsoft.AspNetCore.Razor.Language;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.CodeAnalysis.Razor.Serialization
{
internal class TagHelperDescriptorJsonConverter : JsonConverter
{
public static readonly TagHelperDescriptorJsonConverter Instance = new TagHelperDescriptorJsonConverter();
public override bool CanConvert(Type objectType)
{
return typeof(TagHelperDescriptor).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartObject)
{
return null;
}
var descriptor = JObject.Load(reader);
var descriptorKind = descriptor[nameof(TagHelperDescriptor.Kind)].Value<string>();
var typeName = descriptor[nameof(TagHelperDescriptor.Name)].Value<string>();
var assemblyName = descriptor[nameof(TagHelperDescriptor.AssemblyName)].Value<string>();
var tagMatchingRules = descriptor[nameof(TagHelperDescriptor.TagMatchingRules)].Value<JArray>();
var boundAttributes = descriptor[nameof(TagHelperDescriptor.BoundAttributes)].Value<JArray>();
var childTags = descriptor[nameof(TagHelperDescriptor.AllowedChildTags)].Value<JArray>();
var documentation = descriptor[nameof(TagHelperDescriptor.Documentation)].Value<string>();
var tagOutputHint = descriptor[nameof(TagHelperDescriptor.TagOutputHint)].Value<string>();
var caseSensitive = descriptor[nameof(TagHelperDescriptor.CaseSensitive)].Value<bool>();
var diagnostics = descriptor[nameof(TagHelperDescriptor.Diagnostics)].Value<JArray>();
var metadata = descriptor[nameof(TagHelperDescriptor.Metadata)].Value<JObject>();
var builder = TagHelperDescriptorBuilder.Create(descriptorKind, typeName, assemblyName);
builder.Documentation = documentation;
builder.TagOutputHint = tagOutputHint;
builder.CaseSensitive = caseSensitive;
foreach (var tagMatchingRule in tagMatchingRules)
{
var rule = tagMatchingRule.Value<JObject>();
builder.TagMatchingRule(b => ReadTagMatchingRule(b, rule, serializer));
}
foreach (var boundAttribute in boundAttributes)
{
var attribute = boundAttribute.Value<JObject>();
builder.BindAttribute(b => ReadBoundAttribute(b, attribute, serializer));
}
foreach (var childTag in childTags)
{
var tag = childTag.Value<JObject>();
builder.AllowChildTag(childTagBuilder => ReadAllowedChildTag(childTagBuilder, tag, serializer));
}
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
var metadataReader = metadata.CreateReader();
var metadataValue = serializer.Deserialize<Dictionary<string, string>>(metadataReader);
foreach (var item in metadataValue)
{
builder.Metadata[item.Key] = item.Value;
}
return builder.Build();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var tagHelper = (TagHelperDescriptor)value;
writer.WriteStartObject();
writer.WritePropertyName(nameof(TagHelperDescriptor.Kind));
writer.WriteValue(tagHelper.Kind);
writer.WritePropertyName(nameof(TagHelperDescriptor.Name));
writer.WriteValue(tagHelper.Name);
writer.WritePropertyName(nameof(TagHelperDescriptor.AssemblyName));
writer.WriteValue(tagHelper.AssemblyName);
writer.WritePropertyName(nameof(TagHelperDescriptor.Documentation));
writer.WriteValue(tagHelper.Documentation);
writer.WritePropertyName(nameof(TagHelperDescriptor.TagOutputHint));
writer.WriteValue(tagHelper.TagOutputHint);
writer.WritePropertyName(nameof(TagHelperDescriptor.CaseSensitive));
writer.WriteValue(tagHelper.CaseSensitive);
writer.WritePropertyName(nameof(TagHelperDescriptor.TagMatchingRules));
writer.WriteStartArray();
foreach (var ruleDescriptor in tagHelper.TagMatchingRules)
{
WriteTagMatchingRule(writer, ruleDescriptor, serializer);
}
writer.WriteEndArray();
writer.WritePropertyName(nameof(TagHelperDescriptor.BoundAttributes));
writer.WriteStartArray();
foreach (var boundAttribute in tagHelper.BoundAttributes)
{
WriteBoundAttribute(writer, boundAttribute, serializer);
}
writer.WriteEndArray();
writer.WritePropertyName(nameof(TagHelperDescriptor.AllowedChildTags));
writer.WriteStartArray();
foreach (var allowedChildTag in tagHelper.AllowedChildTags)
{
WriteAllowedChildTags(writer, allowedChildTag, serializer);
}
writer.WriteEndArray();
writer.WritePropertyName(nameof(TagHelperDescriptor.Diagnostics));
serializer.Serialize(writer, tagHelper.Diagnostics);
writer.WritePropertyName(nameof(TagHelperDescriptor.Metadata));
WriteMetadata(writer, tagHelper.Metadata);
writer.WriteEndObject();
}
private static void WriteAllowedChildTags(JsonWriter writer, AllowedChildTagDescriptor allowedChildTag, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(AllowedChildTagDescriptor.Name));
writer.WriteValue(allowedChildTag.Name);
writer.WritePropertyName(nameof(AllowedChildTagDescriptor.DisplayName));
writer.WriteValue(allowedChildTag.DisplayName);
writer.WritePropertyName(nameof(AllowedChildTagDescriptor.Diagnostics));
serializer.Serialize(writer, allowedChildTag.Diagnostics);
writer.WriteEndObject();
}
private static void WriteBoundAttribute(JsonWriter writer, BoundAttributeDescriptor boundAttribute, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(BoundAttributeDescriptor.Kind));
writer.WriteValue(boundAttribute.Kind);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.Name));
writer.WriteValue(boundAttribute.Name);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.TypeName));
writer.WriteValue(boundAttribute.TypeName);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.IsEnum));
writer.WriteValue(boundAttribute.IsEnum);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.IndexerNamePrefix));
writer.WriteValue(boundAttribute.IndexerNamePrefix);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.IndexerTypeName));
writer.WriteValue(boundAttribute.IndexerTypeName);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.Documentation));
writer.WriteValue(boundAttribute.Documentation);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.Diagnostics));
serializer.Serialize(writer, boundAttribute.Diagnostics);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.Metadata));
WriteMetadata(writer, boundAttribute.Metadata);
writer.WritePropertyName(nameof(BoundAttributeDescriptor.BoundAttributeParameters));
writer.WriteStartArray();
foreach (var boundAttributeParameter in boundAttribute.BoundAttributeParameters)
{
WriteBoundAttributeParameter(writer, boundAttributeParameter, serializer);
}
writer.WriteEndArray();
writer.WriteEndObject();
}
private static void WriteBoundAttributeParameter(JsonWriter writer, BoundAttributeParameterDescriptor boundAttributeParameter, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.Kind));
writer.WriteValue(boundAttributeParameter.Kind);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.Name));
writer.WriteValue(boundAttributeParameter.Name);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.TypeName));
writer.WriteValue(boundAttributeParameter.TypeName);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.IsEnum));
writer.WriteValue(boundAttributeParameter.IsEnum);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.Documentation));
writer.WriteValue(boundAttributeParameter.Documentation);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.Diagnostics));
serializer.Serialize(writer, boundAttributeParameter.Diagnostics);
writer.WritePropertyName(nameof(BoundAttributeParameterDescriptor.Metadata));
WriteMetadata(writer, boundAttributeParameter.Metadata);
writer.WriteEndObject();
}
private static void WriteMetadata(JsonWriter writer, IReadOnlyDictionary<string, string> metadata)
{
writer.WriteStartObject();
foreach (var kvp in metadata)
{
writer.WritePropertyName(kvp.Key);
writer.WriteValue(kvp.Value);
}
writer.WriteEndObject();
}
private static void WriteTagMatchingRule(JsonWriter writer, TagMatchingRuleDescriptor ruleDescriptor, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(TagMatchingRuleDescriptor.TagName));
writer.WriteValue(ruleDescriptor.TagName);
writer.WritePropertyName(nameof(TagMatchingRuleDescriptor.ParentTag));
writer.WriteValue(ruleDescriptor.ParentTag);
writer.WritePropertyName(nameof(TagMatchingRuleDescriptor.TagStructure));
writer.WriteValue(ruleDescriptor.TagStructure);
writer.WritePropertyName(nameof(TagMatchingRuleDescriptor.Attributes));
writer.WriteStartArray();
foreach (var requiredAttribute in ruleDescriptor.Attributes)
{
WriteRequiredAttribute(writer, requiredAttribute, serializer);
}
writer.WriteEndArray();
writer.WritePropertyName(nameof(TagMatchingRuleDescriptor.Diagnostics));
serializer.Serialize(writer, ruleDescriptor.Diagnostics);
writer.WriteEndObject();
}
private static void WriteRequiredAttribute(JsonWriter writer, RequiredAttributeDescriptor requiredAttribute, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.Name));
writer.WriteValue(requiredAttribute.Name);
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.NameComparison));
writer.WriteValue(requiredAttribute.NameComparison);
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.Value));
writer.WriteValue(requiredAttribute.Value);
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.ValueComparison));
writer.WriteValue(requiredAttribute.ValueComparison);
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.Diagnostics));
serializer.Serialize(writer, requiredAttribute.Diagnostics);
writer.WritePropertyName(nameof(RequiredAttributeDescriptor.Metadata));
WriteMetadata(writer, requiredAttribute.Metadata);
writer.WriteEndObject();
}
private static void ReadTagMatchingRule(TagMatchingRuleDescriptorBuilder builder, JObject rule, JsonSerializer serializer)
{
var tagName = rule[nameof(TagMatchingRuleDescriptor.TagName)].Value<string>();
var attributes = rule[nameof(TagMatchingRuleDescriptor.Attributes)].Value<JArray>();
var parentTag = rule[nameof(TagMatchingRuleDescriptor.ParentTag)].Value<string>();
var tagStructure = rule[nameof(TagMatchingRuleDescriptor.TagStructure)].Value<int>();
var diagnostics = rule[nameof(TagMatchingRuleDescriptor.Diagnostics)].Value<JArray>();
builder.TagName = tagName;
builder.ParentTag = parentTag;
builder.TagStructure = (TagStructure)tagStructure;
foreach (var attribute in attributes)
{
var attibuteValue = attribute.Value<JObject>();
builder.Attribute(b => ReadRequiredAttribute(b, attibuteValue, serializer));
}
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
}
private static void ReadRequiredAttribute(RequiredAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer)
{
var name = attribute[nameof(RequiredAttributeDescriptor.Name)].Value<string>();
var nameComparison = attribute[nameof(RequiredAttributeDescriptor.NameComparison)].Value<int>();
var value = attribute[nameof(RequiredAttributeDescriptor.Value)].Value<string>();
var valueComparison = attribute[nameof(RequiredAttributeDescriptor.ValueComparison)].Value<int>();
var diagnostics = attribute[nameof(RequiredAttributeDescriptor.Diagnostics)].Value<JArray>();
var metadata = attribute[nameof(RequiredAttributeDescriptor.Metadata)].Value<JObject>();
builder.Name = name;
builder.NameComparisonMode = (RequiredAttributeDescriptor.NameComparisonMode)nameComparison;
builder.Value = value;
builder.ValueComparisonMode = (RequiredAttributeDescriptor.ValueComparisonMode)valueComparison;
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
var metadataReader = metadata.CreateReader();
var metadataValue = serializer.Deserialize<Dictionary<string, string>>(metadataReader);
foreach (var item in metadataValue)
{
builder.Metadata[item.Key] = item.Value;
}
}
private static void ReadAllowedChildTag(AllowedChildTagDescriptorBuilder builder, JObject childTag, JsonSerializer serializer)
{
var name = childTag[nameof(AllowedChildTagDescriptor.Name)].Value<string>();
var displayName = childTag[nameof(AllowedChildTagDescriptor.DisplayName)].Value<string>();
var diagnostics = childTag[nameof(AllowedChildTagDescriptor.Diagnostics)].Value<JArray>();
builder.Name = name;
builder.DisplayName = displayName;
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
}
private static void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer)
{
var descriptorKind = attribute[nameof(BoundAttributeDescriptor.Kind)].Value<string>();
var name = attribute[nameof(BoundAttributeDescriptor.Name)].Value<string>();
var typeName = attribute[nameof(BoundAttributeDescriptor.TypeName)].Value<string>();
var isEnum = attribute[nameof(BoundAttributeDescriptor.IsEnum)].Value<bool>();
var indexerNamePrefix = attribute[nameof(BoundAttributeDescriptor.IndexerNamePrefix)].Value<string>();
var indexerTypeName = attribute[nameof(BoundAttributeDescriptor.IndexerTypeName)].Value<string>();
var documentation = attribute[nameof(BoundAttributeDescriptor.Documentation)].Value<string>();
var diagnostics = attribute[nameof(BoundAttributeDescriptor.Diagnostics)].Value<JArray>();
var metadata = attribute[nameof(BoundAttributeDescriptor.Metadata)].Value<JObject>();
var boundAttributeParameters = attribute[nameof(BoundAttributeDescriptor.BoundAttributeParameters)].Value<JArray>();
builder.Name = name;
builder.TypeName = typeName;
builder.Documentation = documentation;
if (indexerNamePrefix != null)
{
builder.AsDictionary(indexerNamePrefix, indexerTypeName);
}
if (isEnum)
{
builder.IsEnum = true;
}
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
var metadataReader = metadata.CreateReader();
var metadataValue = serializer.Deserialize<Dictionary<string, string>>(metadataReader);
foreach (var item in metadataValue)
{
builder.Metadata[item.Key] = item.Value;
}
foreach (var boundAttributeParameter in boundAttributeParameters)
{
var parameter = boundAttributeParameter.Value<JObject>();
builder.BindAttributeParameter(b => ReadBoundAttributeParameter(b, parameter, serializer));
}
}
private static void ReadBoundAttributeParameter(BoundAttributeParameterDescriptorBuilder builder, JObject parameter, JsonSerializer serializer)
{
var descriptorKind = parameter[nameof(BoundAttributeParameterDescriptor.Kind)].Value<string>();
var name = parameter[nameof(BoundAttributeParameterDescriptor.Name)].Value<string>();
var typeName = parameter[nameof(BoundAttributeParameterDescriptor.TypeName)].Value<string>();
var isEnum = parameter[nameof(BoundAttributeParameterDescriptor.IsEnum)].Value<bool>();
var documentation = parameter[nameof(BoundAttributeParameterDescriptor.Documentation)].Value<string>();
var diagnostics = parameter[nameof(BoundAttributeParameterDescriptor.Diagnostics)].Value<JArray>();
var metadata = parameter[nameof(BoundAttributeParameterDescriptor.Metadata)].Value<JObject>();
builder.Name = name;
builder.TypeName = typeName;
builder.Documentation = documentation;
if (isEnum)
{
builder.IsEnum = true;
}
foreach (var diagnostic in diagnostics)
{
var diagnosticReader = diagnostic.CreateReader();
var diagnosticObject = serializer.Deserialize<RazorDiagnostic>(diagnosticReader);
builder.Diagnostics.Add(diagnosticObject);
}
var metadataReader = metadata.CreateReader();
var metadataValue = serializer.Deserialize<Dictionary<string, string>>(metadataReader);
foreach (var item in metadataValue)
{
builder.Metadata[item.Key] = item.Value;
}
}
}
}