Enable serialization of `TagHelperDescriptor`s.
- Added ability for TagHelpers to write their own json output.
This commit is contained in:
parent
de9c5b3909
commit
93d8a93498
|
|
@ -13,8 +13,6 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Serialization
|
|||
{
|
||||
public static readonly TagHelperDescriptorJsonConverter Instance = new TagHelperDescriptorJsonConverter();
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(TagHelperDescriptor).IsAssignableFrom(objectType);
|
||||
|
|
@ -81,9 +79,166 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Serialization
|
|||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
// We should never get here because CanWrite returns false.
|
||||
// We want the default serializer to handle TagHelperDescriptor serialization.
|
||||
throw new NotImplementedException();
|
||||
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.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 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 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.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 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 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.WriteEndObject();
|
||||
}
|
||||
|
||||
private void ReadTagMatchingRule(TagMatchingRuleDescriptorBuilder builder, JObject rule, JsonSerializer serializer)
|
||||
|
|
|
|||
|
|
@ -7,12 +7,66 @@ using Microsoft.AspNetCore.Mvc.Razor.Extensions;
|
|||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||
{
|
||||
public class TagHelperDescriptorSerializationTest
|
||||
{
|
||||
[Fact]
|
||||
public void TagHelperDescriptor_CanReadCamelCasedData()
|
||||
{
|
||||
// Arrange
|
||||
var expectedDescriptor = CreateTagHelperDescriptor(
|
||||
kind: TagHelperConventions.DefaultKind,
|
||||
tagName: "tag-name",
|
||||
typeName: "type name",
|
||||
assemblyName: "assembly name",
|
||||
attributes: new Action<BoundAttributeDescriptorBuilder>[]
|
||||
{
|
||||
builder => builder
|
||||
.Name("test-attribute")
|
||||
.PropertyName("TestAttribute")
|
||||
.TypeName("string"),
|
||||
},
|
||||
ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
|
||||
{
|
||||
builder => builder
|
||||
.RequireAttributeDescriptor(attribute => attribute
|
||||
.Name("required-attribute-one")
|
||||
.NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch))
|
||||
.RequireAttributeDescriptor(attribute => attribute
|
||||
.Name("required-attribute-two")
|
||||
.NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
|
||||
.Value("something")
|
||||
.ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.PrefixMatch))
|
||||
.RequireParentTag("parent-name")
|
||||
.RequireTagStructure(TagStructure.WithoutEndTag),
|
||||
},
|
||||
configureAction: builder =>
|
||||
{
|
||||
builder.AllowChildTag("allowed-child-one");
|
||||
builder.AddMetadata("foo", "bar");
|
||||
});
|
||||
var serializerSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver(),
|
||||
Converters = new List<JsonConverter>
|
||||
{
|
||||
TagHelperDescriptorJsonConverter.Instance,
|
||||
RazorDiagnosticJsonConverter.Instance,
|
||||
}
|
||||
};
|
||||
var serializedDescriptor = JsonConvert.SerializeObject(expectedDescriptor, serializerSettings);
|
||||
|
||||
// Act
|
||||
var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor, TagHelperDescriptorJsonConverter.Instance, RazorDiagnosticJsonConverter.Instance);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptor, descriptor, TagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TagHelperDescriptor_RoundTripsProperly()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue