Add AllowedChildTagDescriptor.

- Changed the `AllowedChildTags` collection on `TagHelperDescriptor` to have a custom object type to represent child tags.
- Created comparers and builders to work with the child tag descriptor.
- Removed the validation methods on `TagHelperDescriptorBuilder` since there's no longer any bits to validate (they're contained within the sub-properties).
- Unit tested the `DisplayName`.

#1493
This commit is contained in:
N. Taylor Mullen 2017-06-30 16:18:33 -07:00
parent a7cc63d6e1
commit 4654997201
17 changed files with 341 additions and 70 deletions

View File

@ -0,0 +1,45 @@
// 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 System.Diagnostics;
using System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
[DebuggerDisplay("{DisplayName,nq}")]
public abstract class AllowedChildTagDescriptor : IEquatable<AllowedChildTagDescriptor>
{
public string Name { get; protected set; }
public string DisplayName { get; protected set; }
public IReadOnlyList<RazorDiagnostic> Diagnostics { get; protected set; }
public bool HasErrors
{
get
{
var errors = Diagnostics.Any(diagnostic => diagnostic.Severity == RazorDiagnosticSeverity.Error);
return errors;
}
}
public bool Equals(AllowedChildTagDescriptor other)
{
return AllowedChildTagDescriptorComparer.Default.Equals(this, other);
}
public override bool Equals(object obj)
{
return Equals(obj as AllowedChildTagDescriptor);
}
public override int GetHashCode()
{
return AllowedChildTagDescriptorComparer.Default.GetHashCode(this);
}
}
}

View File

@ -0,0 +1,17 @@
// 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;
namespace Microsoft.AspNetCore.Razor.Language
{
public abstract class AllowedChildTagDescriptorBuilder
{
public abstract string Name { get; set; }
public abstract string DisplayName { get; set; }
public abstract RazorDiagnosticCollection Diagnostics { get; }
}
}

View File

@ -0,0 +1,73 @@
// 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 System.Linq;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class AllowedChildTagDescriptorComparer : IEqualityComparer<AllowedChildTagDescriptor>
{
/// <summary>
/// A default instance of the <see cref="AllowedChildTagDescriptorComparer"/>.
/// </summary>
public static readonly AllowedChildTagDescriptorComparer Default =
new AllowedChildTagDescriptorComparer();
/// <summary>
/// A default instance of the <see cref="AllowedChildTagDescriptorComparer"/> that does case-sensitive comparison.
/// </summary>
internal static readonly AllowedChildTagDescriptorComparer CaseSensitive =
new AllowedChildTagDescriptorComparer(caseSensitive: true);
private readonly StringComparer _stringComparer;
private readonly StringComparison _stringComparison;
private AllowedChildTagDescriptorComparer(bool caseSensitive = false)
{
if (caseSensitive)
{
_stringComparer = StringComparer.Ordinal;
_stringComparison = StringComparison.Ordinal;
}
else
{
_stringComparer = StringComparer.OrdinalIgnoreCase;
_stringComparison = StringComparison.OrdinalIgnoreCase;
}
}
/// <inheritdoc />
public virtual bool Equals(
AllowedChildTagDescriptor descriptorX,
AllowedChildTagDescriptor descriptorY)
{
if (object.ReferenceEquals(descriptorX, descriptorY))
{
return true;
}
if (descriptorX == null ^ descriptorY == null)
{
return false;
}
return descriptorX != null &&
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics);
}
/// <inheritdoc />
public virtual int GetHashCode(AllowedChildTagDescriptor descriptor)
{
var hashCodeCombiner = HashCodeCombiner.Start();
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
return hashCodeCombiner.CombinedHash;
}
}
}

View File

@ -0,0 +1,15 @@
// 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.
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultAllowedChildTagDescriptor : AllowedChildTagDescriptor
{
public DefaultAllowedChildTagDescriptor(string name, string displayName, RazorDiagnostic[] diagnostics)
{
Name = name;
DisplayName = displayName;
Diagnostics = diagnostics;
}
}
}

View File

@ -0,0 +1,77 @@
// 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 System.Linq;
namespace Microsoft.AspNetCore.Razor.Language
{
internal class DefaultAllowedChildTagDescriptorBuilder : AllowedChildTagDescriptorBuilder
{
private readonly DefaultTagHelperDescriptorBuilder _parent;
private DefaultRazorDiagnosticCollection _diagnostics;
public DefaultAllowedChildTagDescriptorBuilder(DefaultTagHelperDescriptorBuilder parent)
{
_parent = parent;
}
public override string Name { get; set; }
public override string DisplayName { get; set; }
public override RazorDiagnosticCollection Diagnostics
{
get
{
if (_diagnostics == null)
{
_diagnostics = new DefaultRazorDiagnosticCollection();
}
return _diagnostics;
}
}
public AllowedChildTagDescriptor Build()
{
var validationDiagnostics = Validate();
var diagnostics = new HashSet<RazorDiagnostic>(validationDiagnostics);
if (_diagnostics != null)
{
diagnostics.UnionWith(_diagnostics);
}
var displayName = DisplayName ?? Name;
var descriptor = new DefaultAllowedChildTagDescriptor(
Name,
displayName,
diagnostics?.ToArray() ?? Array.Empty<RazorDiagnostic>());
return descriptor;
}
private IEnumerable<RazorDiagnostic> Validate()
{
if (string.IsNullOrWhiteSpace(Name))
{
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(_parent.GetDisplayName());
yield return diagnostic;
}
else if (Name != TagHelperMatchingConventions.ElementCatchAllName)
{
foreach (var character in Name)
{
if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
{
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChild(_parent.GetDisplayName(), Name, character);
yield return diagnostic;
}
}
}
}
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language
string tagOutputHint, string tagOutputHint,
TagMatchingRuleDescriptor[] tagMatchingRules, TagMatchingRuleDescriptor[] tagMatchingRules,
BoundAttributeDescriptor[] attributeDescriptors, BoundAttributeDescriptor[] attributeDescriptors,
string[] allowedChildTags, AllowedChildTagDescriptor[] allowedChildTags,
Dictionary<string, string> metadata, Dictionary<string, string> metadata,
RazorDiagnostic[] diagnostics) RazorDiagnostic[] diagnostics)
: base(kind) : base(kind)

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Razor.Language
// Required values // Required values
private readonly Dictionary<string, string> _metadata; private readonly Dictionary<string, string> _metadata;
private HashSet<string> _allowedChildTags; private List<DefaultAllowedChildTagDescriptorBuilder> _allowedChildTags;
private List<DefaultBoundAttributeDescriptorBuilder> _attributeBuilders; private List<DefaultBoundAttributeDescriptorBuilder> _attributeBuilders;
private List<DefaultTagMatchingRuleDescriptorBuilder> _tagMatchingRuleBuilders; private List<DefaultTagMatchingRuleDescriptorBuilder> _tagMatchingRuleBuilders;
private DefaultRazorDiagnosticCollection _diagnostics; private DefaultRazorDiagnosticCollection _diagnostics;
@ -38,19 +38,6 @@ namespace Microsoft.AspNetCore.Razor.Language
public override string DisplayName { get; set; } public override string DisplayName { get; set; }
public override ICollection<string> AllowedChildTags
{
get
{
if (_allowedChildTags == null)
{
_allowedChildTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
}
return _allowedChildTags;
}
}
public override string TagOutputHint { get; set; } public override string TagOutputHint { get; set; }
public override string Documentation { get; set; } public override string Documentation { get; set; }
@ -70,6 +57,16 @@ namespace Microsoft.AspNetCore.Razor.Language
} }
} }
public override IReadOnlyList<AllowedChildTagDescriptorBuilder> AllowedChildTags
{
get
{
EnsureAllowedChildTags();
return _allowedChildTags;
}
}
public override IReadOnlyList<BoundAttributeDescriptorBuilder> BoundAttributes public override IReadOnlyList<BoundAttributeDescriptorBuilder> BoundAttributes
{ {
get get
@ -90,6 +87,20 @@ namespace Microsoft.AspNetCore.Razor.Language
} }
} }
public override void AllowChildTag(Action<AllowedChildTagDescriptorBuilder> configure)
{
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
EnsureAllowedChildTags();
var builder = new DefaultAllowedChildTagDescriptorBuilder(this);
configure(builder);
_allowedChildTags.Add(builder);
}
public override void BindAttribute(Action<BoundAttributeDescriptorBuilder> configure) public override void BindAttribute(Action<BoundAttributeDescriptorBuilder> configure)
{ {
if (configure == null) if (configure == null)
@ -120,13 +131,24 @@ namespace Microsoft.AspNetCore.Razor.Language
public override TagHelperDescriptor Build() public override TagHelperDescriptor Build()
{ {
var validationDiagnostics = Validate(); var diagnostics = new HashSet<RazorDiagnostic>();
var diagnostics = new HashSet<RazorDiagnostic>(validationDiagnostics);
if (_diagnostics != null) if (_diagnostics != null)
{ {
diagnostics.UnionWith(_diagnostics); diagnostics.UnionWith(_diagnostics);
} }
var allowedChildTags = Array.Empty<AllowedChildTagDescriptor>();
if (_allowedChildTags != null)
{
var allowedChildTagsSet = new HashSet<AllowedChildTagDescriptor>(AllowedChildTagDescriptorComparer.Default);
for (var i = 0; i < _allowedChildTags.Count; i++)
{
allowedChildTagsSet.Add(_allowedChildTags[i].Build());
}
allowedChildTags = allowedChildTagsSet.ToArray();
}
var tagMatchingRules = Array.Empty<TagMatchingRuleDescriptor>(); var tagMatchingRules = Array.Empty<TagMatchingRuleDescriptor>();
if (_tagMatchingRuleBuilders != null) if (_tagMatchingRuleBuilders != null)
{ {
@ -160,7 +182,7 @@ namespace Microsoft.AspNetCore.Razor.Language
TagOutputHint, TagOutputHint,
tagMatchingRules, tagMatchingRules,
attributes, attributes,
_allowedChildTags?.ToArray() ?? Array.Empty<string>(), allowedChildTags,
new Dictionary<string, string>(_metadata), new Dictionary<string, string>(_metadata),
diagnostics.ToArray()); diagnostics.ToArray());
@ -188,31 +210,11 @@ namespace Microsoft.AspNetCore.Razor.Language
return this.GetTypeName() ?? Name; return this.GetTypeName() ?? Name;
} }
private IEnumerable<RazorDiagnostic> Validate() private void EnsureAllowedChildTags()
{ {
if (_allowedChildTags != null) if (_allowedChildTags == null)
{ {
foreach (var name in _allowedChildTags) _allowedChildTags = new List<DefaultAllowedChildTagDescriptorBuilder>();
{
if (string.IsNullOrWhiteSpace(name))
{
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(GetDisplayName());
yield return diagnostic;
}
else if (name != TagHelperMatchingConventions.ElementCatchAllName)
{
foreach (var character in name)
{
if (char.IsWhiteSpace(character) || HtmlConventions.InvalidNonWhitespaceHtmlCharacters.Contains(character))
{
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InvalidRestrictedChild(GetDisplayName(), name, character);
yield return diagnostic;
}
}
}
}
} }
} }

View File

@ -855,7 +855,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{ {
AllowedChildren = Builder.BindingResult.Descriptors AllowedChildren = Builder.BindingResult.Descriptors
.Where(descriptor => descriptor.AllowedChildTags != null) .Where(descriptor => descriptor.AllowedChildTags != null)
.SelectMany(descriptor => descriptor.AllowedChildTags) .SelectMany(descriptor => descriptor.AllowedChildTags.Select(childTag => childTag.Name))
.Distinct(StringComparer.OrdinalIgnoreCase) .Distinct(StringComparer.OrdinalIgnoreCase)
.ToList(); .ToList();
} }

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Razor.Language
public IEnumerable<BoundAttributeDescriptor> BoundAttributes { get; protected set; } public IEnumerable<BoundAttributeDescriptor> BoundAttributes { get; protected set; }
public IEnumerable<string> AllowedChildTags { get; protected set; } public IEnumerable<AllowedChildTagDescriptor> AllowedChildTags { get; protected set; }
public string Documentation { get; protected set; } public string Documentation { get; protected set; }
@ -55,9 +55,13 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
if (_allDiagnostics == null) if (_allDiagnostics == null)
{ {
var allowedChildTagDiagnostics = AllowedChildTags.SelectMany(childTag => childTag.Diagnostics);
var attributeDiagnostics = BoundAttributes.SelectMany(attribute => attribute.Diagnostics); var attributeDiagnostics = BoundAttributes.SelectMany(attribute => attribute.Diagnostics);
var ruleDiagnostics = TagMatchingRules.SelectMany(rule => rule.GetAllDiagnostics()); var ruleDiagnostics = TagMatchingRules.SelectMany(rule => rule.GetAllDiagnostics());
var combinedDiagnostics = attributeDiagnostics.Concat(ruleDiagnostics).Concat(Diagnostics); var combinedDiagnostics = allowedChildTagDiagnostics
.Concat(attributeDiagnostics)
.Concat(ruleDiagnostics)
.Concat(Diagnostics);
_allDiagnostics = combinedDiagnostics.ToArray(); _allDiagnostics = combinedDiagnostics.ToArray();
} }

View File

@ -54,16 +54,18 @@ namespace Microsoft.AspNetCore.Razor.Language
public abstract string Documentation { get; set; } public abstract string Documentation { get; set; }
public abstract ICollection<string> AllowedChildTags { get; }
public abstract IDictionary<string, string> Metadata { get; } public abstract IDictionary<string, string> Metadata { get; }
public abstract RazorDiagnosticCollection Diagnostics { get; } public abstract RazorDiagnosticCollection Diagnostics { get; }
public abstract IReadOnlyList<AllowedChildTagDescriptorBuilder> AllowedChildTags { get; }
public abstract IReadOnlyList<BoundAttributeDescriptorBuilder> BoundAttributes { get; } public abstract IReadOnlyList<BoundAttributeDescriptorBuilder> BoundAttributes { get; }
public abstract IReadOnlyList<TagMatchingRuleDescriptorBuilder> TagMatchingRules { get; } public abstract IReadOnlyList<TagMatchingRuleDescriptorBuilder> TagMatchingRules { get; }
public abstract void AllowChildTag(Action<AllowedChildTagDescriptorBuilder> configure);
public abstract void BindAttribute(Action<BoundAttributeDescriptorBuilder> configure); public abstract void BindAttribute(Action<BoundAttributeDescriptorBuilder> configure);
public abstract void TagMatchingRule(Action<TagMatchingRuleDescriptorBuilder> configure); public abstract void TagMatchingRule(Action<TagMatchingRuleDescriptorBuilder> configure);

View File

@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language
private readonly StringComparer _stringComparer; private readonly StringComparer _stringComparer;
private readonly StringComparison _stringComparison; private readonly StringComparison _stringComparison;
private readonly AllowedChildTagDescriptorComparer _AllowedChildTagDescriptorComparer;
private readonly BoundAttributeDescriptorComparer _boundAttributeComparer; private readonly BoundAttributeDescriptorComparer _boundAttributeComparer;
private readonly TagMatchingRuleDescriptorComparer _tagMatchingRuleComparer; private readonly TagMatchingRuleDescriptorComparer _tagMatchingRuleComparer;
@ -32,6 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
_stringComparer = StringComparer.Ordinal; _stringComparer = StringComparer.Ordinal;
_stringComparison = StringComparison.Ordinal; _stringComparison = StringComparison.Ordinal;
_AllowedChildTagDescriptorComparer = AllowedChildTagDescriptorComparer.CaseSensitive;
_boundAttributeComparer = BoundAttributeDescriptorComparer.CaseSensitive; _boundAttributeComparer = BoundAttributeDescriptorComparer.CaseSensitive;
_tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.CaseSensitive; _tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.CaseSensitive;
} }
@ -39,6 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
_stringComparer = StringComparer.OrdinalIgnoreCase; _stringComparer = StringComparer.OrdinalIgnoreCase;
_stringComparison = StringComparison.OrdinalIgnoreCase; _stringComparison = StringComparison.OrdinalIgnoreCase;
_AllowedChildTagDescriptorComparer = AllowedChildTagDescriptorComparer.Default;
_boundAttributeComparer = BoundAttributeDescriptorComparer.Default; _boundAttributeComparer = BoundAttributeDescriptorComparer.Default;
_tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.Default; _tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.Default;
} }
@ -71,9 +74,9 @@ namespace Microsoft.AspNetCore.Razor.Language
(descriptorX.AllowedChildTags != null && (descriptorX.AllowedChildTags != null &&
descriptorY.AllowedChildTags != null && descriptorY.AllowedChildTags != null &&
Enumerable.SequenceEqual( Enumerable.SequenceEqual(
descriptorX.AllowedChildTags.OrderBy(child => child, _stringComparer), descriptorX.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer),
descriptorY.AllowedChildTags.OrderBy(child => child, _stringComparer), descriptorY.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer),
_stringComparer))) && _AllowedChildTagDescriptorComparer))) &&
string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) && string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) &&
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) && string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
string.Equals(descriptorX.TagOutputHint, descriptorY.TagOutputHint, _stringComparison) && string.Equals(descriptorX.TagOutputHint, descriptorY.TagOutputHint, _stringComparison) &&
@ -95,6 +98,12 @@ namespace Microsoft.AspNetCore.Razor.Language
hashCodeCombiner.Add(descriptor.Kind); hashCodeCombiner.Add(descriptor.Kind);
hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal); hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal);
var childTags = descriptor.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer);
foreach (var childTag in childTags)
{
hashCodeCombiner.Add(_AllowedChildTagDescriptorComparer.GetHashCode(childTag));
}
var boundAttributes = descriptor.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer); var boundAttributes = descriptor.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer);
foreach (var attribute in boundAttributes) foreach (var attribute in boundAttributes)
{ {
@ -111,15 +120,6 @@ namespace Microsoft.AspNetCore.Razor.Language
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal); hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
hashCodeCombiner.Add(descriptor.TagOutputHint, _stringComparer); hashCodeCombiner.Add(descriptor.TagOutputHint, _stringComparer);
if (descriptor.AllowedChildTags != null)
{
var allowedChildren = descriptor.AllowedChildTags.OrderBy(child => child, _stringComparer);
foreach (var child in allowedChildren)
{
hashCodeCombiner.Add(child, _stringComparer);
}
}
return hashCodeCombiner.CombinedHash; return hashCodeCombiner.CombinedHash;
} }
} }

View File

@ -141,13 +141,13 @@ namespace Microsoft.CodeAnalysis.Razor
return; return;
} }
builder.AllowedChildTags.Add((string)restrictChildrenAttribute.ConstructorArguments[0].Value); builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = (string)restrictChildrenAttribute.ConstructorArguments[0].Value);
if (restrictChildrenAttribute.ConstructorArguments.Length == 2) if (restrictChildrenAttribute.ConstructorArguments.Length == 2)
{ {
foreach (var value in restrictChildrenAttribute.ConstructorArguments[1].Values) foreach (var value in restrictChildrenAttribute.ConstructorArguments[1].Values)
{ {
builder.AllowedChildTags.Add((string)value.Value); builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = (string)value.Value);
} }
} }
} }

View File

@ -244,14 +244,9 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
foreach (var descriptor in binding.Descriptors) foreach (var descriptor in binding.Descriptors)
{ {
if (descriptor.AllowedChildTags == null)
{
continue;
}
foreach (var childTag in descriptor.AllowedChildTags) foreach (var childTag in descriptor.AllowedChildTags)
{ {
var prefixedName = string.Concat(prefix, childTag); var prefixedName = string.Concat(prefix, childTag.Name);
var descriptors = _tagHelperFactsService.GetTagHelpersGivenTag( var descriptors = _tagHelperFactsService.GetTagHelpersGivenTag(
completionContext.DocumentContext, completionContext.DocumentContext,
prefixedName, prefixedName,

View File

@ -58,8 +58,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
foreach (var childTag in childTags) foreach (var childTag in childTags)
{ {
var tagValue = childTag.Value<string>(); var tag = childTag.Value<JObject>();
builder.AllowedChildTags.Add(tagValue); builder.AllowChildTag(childTagBuilder => ReadAllowedChildTag(childTagBuilder, tag, serializer));
} }
foreach (var diagnostic in diagnostics) foreach (var diagnostic in diagnostics)
@ -133,6 +133,23 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
} }
} }
private 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 void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer) private void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer)
{ {
var descriptorKind = attribute[nameof(BoundAttributeDescriptor.Kind)].Value<string>(); var descriptorKind = attribute[nameof(BoundAttributeDescriptor.Kind)].Value<string>();

View File

@ -0,0 +1,24 @@
// 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 Xunit;
namespace Microsoft.AspNetCore.Razor.Language
{
public class DefaultAllowedChildTagDescriptorBuilderTest
{
[Fact]
public void Build_DisplayNameIsName()
{
// Arrange
var builder = new DefaultAllowedChildTagDescriptorBuilder(null);
builder.Name = "foo";
// Act
var descriptor = builder.Build();
// Assert
Assert.Equal("foo", descriptor.DisplayName);
}
}
}

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language
throw new ArgumentNullException(nameof(builder)); throw new ArgumentNullException(nameof(builder));
} }
builder.AllowedChildTags.Add(allowedChild); builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = allowedChild);
return builder; return builder;
} }

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language
throw new ArgumentNullException(nameof(builder)); throw new ArgumentNullException(nameof(builder));
} }
builder.AllowedChildTags.Add(allowedChild); builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = allowedChild);
return builder; return builder;
} }