diff --git a/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptor.cs b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptor.cs new file mode 100644 index 0000000000..ba2c593313 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptor.cs @@ -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 + { + public string Name { get; protected set; } + + public string DisplayName { get; protected set; } + + public IReadOnlyList 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); + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorBuilder.cs new file mode 100644 index 0000000000..46fc3cc6aa --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorBuilder.cs @@ -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; } + + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorComparer.cs b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorComparer.cs new file mode 100644 index 0000000000..d73e3ec71e --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/AllowedChildTagDescriptorComparer.cs @@ -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 + { + /// + /// A default instance of the . + /// + public static readonly AllowedChildTagDescriptorComparer Default = + new AllowedChildTagDescriptorComparer(); + + /// + /// A default instance of the that does case-sensitive comparison. + /// + 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; + } + } + + /// + 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); + } + + /// + public virtual int GetHashCode(AllowedChildTagDescriptor descriptor) + { + var hashCodeCombiner = HashCodeCombiner.Start(); + hashCodeCombiner.Add(descriptor.Name, _stringComparer); + hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal); + + return hashCodeCombiner.CombinedHash; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptor.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptor.cs new file mode 100644 index 0000000000..28fa3f0b68 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptor.cs @@ -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; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptorBuilder.cs new file mode 100644 index 0000000000..75897d93fc --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultAllowedChildTagDescriptorBuilder.cs @@ -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(validationDiagnostics); + if (_diagnostics != null) + { + diagnostics.UnionWith(_diagnostics); + } + + var displayName = DisplayName ?? Name; + var descriptor = new DefaultAllowedChildTagDescriptor( + Name, + displayName, + diagnostics?.ToArray() ?? Array.Empty()); + + return descriptor; + } + + private IEnumerable 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; + } + } + } + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptor.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptor.cs index c9e3cd55eb..f9da39f401 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptor.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptor.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language string tagOutputHint, TagMatchingRuleDescriptor[] tagMatchingRules, BoundAttributeDescriptor[] attributeDescriptors, - string[] allowedChildTags, + AllowedChildTagDescriptor[] allowedChildTags, Dictionary metadata, RazorDiagnostic[] diagnostics) : base(kind) diff --git a/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptorBuilder.cs index f7500b9a3f..703bd65c02 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptorBuilder.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/DefaultTagHelperDescriptorBuilder.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Razor.Language // Required values private readonly Dictionary _metadata; - private HashSet _allowedChildTags; + private List _allowedChildTags; private List _attributeBuilders; private List _tagMatchingRuleBuilders; private DefaultRazorDiagnosticCollection _diagnostics; @@ -38,19 +38,6 @@ namespace Microsoft.AspNetCore.Razor.Language public override string DisplayName { get; set; } - public override ICollection AllowedChildTags - { - get - { - if (_allowedChildTags == null) - { - _allowedChildTags = new HashSet(StringComparer.OrdinalIgnoreCase); - } - - return _allowedChildTags; - } - } - public override string TagOutputHint { get; set; } public override string Documentation { get; set; } @@ -70,6 +57,16 @@ namespace Microsoft.AspNetCore.Razor.Language } } + public override IReadOnlyList AllowedChildTags + { + get + { + EnsureAllowedChildTags(); + + return _allowedChildTags; + } + } + public override IReadOnlyList BoundAttributes { get @@ -90,6 +87,20 @@ namespace Microsoft.AspNetCore.Razor.Language } } + public override void AllowChildTag(Action 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 configure) { if (configure == null) @@ -120,13 +131,24 @@ namespace Microsoft.AspNetCore.Razor.Language public override TagHelperDescriptor Build() { - var validationDiagnostics = Validate(); - var diagnostics = new HashSet(validationDiagnostics); + var diagnostics = new HashSet(); if (_diagnostics != null) { diagnostics.UnionWith(_diagnostics); } + var allowedChildTags = Array.Empty(); + if (_allowedChildTags != null) + { + var allowedChildTagsSet = new HashSet(AllowedChildTagDescriptorComparer.Default); + for (var i = 0; i < _allowedChildTags.Count; i++) + { + allowedChildTagsSet.Add(_allowedChildTags[i].Build()); + } + + allowedChildTags = allowedChildTagsSet.ToArray(); + } + var tagMatchingRules = Array.Empty(); if (_tagMatchingRuleBuilders != null) { @@ -160,7 +182,7 @@ namespace Microsoft.AspNetCore.Razor.Language TagOutputHint, tagMatchingRules, attributes, - _allowedChildTags?.ToArray() ?? Array.Empty(), + allowedChildTags, new Dictionary(_metadata), diagnostics.ToArray()); @@ -188,31 +210,11 @@ namespace Microsoft.AspNetCore.Razor.Language return this.GetTypeName() ?? Name; } - private IEnumerable Validate() + private void EnsureAllowedChildTags() { - if (_allowedChildTags != null) + if (_allowedChildTags == null) { - foreach (var name in _allowedChildTags) - { - 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; - } - } - } - } + _allowedChildTags = new List(); } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs index f138573498..b38c477b58 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/TagHelperParseTreeRewriter.cs @@ -855,7 +855,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { AllowedChildren = Builder.BindingResult.Descriptors .Where(descriptor => descriptor.AllowedChildTags != null) - .SelectMany(descriptor => descriptor.AllowedChildTags) + .SelectMany(descriptor => descriptor.AllowedChildTags.Select(childTag => childTag.Name)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); } diff --git a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptor.cs b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptor.cs index 6ad3528353..2f0e329dc8 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptor.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptor.cs @@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Razor.Language public IEnumerable BoundAttributes { get; protected set; } - public IEnumerable AllowedChildTags { get; protected set; } + public IEnumerable AllowedChildTags { get; protected set; } public string Documentation { get; protected set; } @@ -55,9 +55,13 @@ namespace Microsoft.AspNetCore.Razor.Language { if (_allDiagnostics == null) { + var allowedChildTagDiagnostics = AllowedChildTags.SelectMany(childTag => childTag.Diagnostics); var attributeDiagnostics = BoundAttributes.SelectMany(attribute => attribute.Diagnostics); 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(); } diff --git a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorBuilder.cs b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorBuilder.cs index 000c4844d5..57a75bf50a 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorBuilder.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorBuilder.cs @@ -54,16 +54,18 @@ namespace Microsoft.AspNetCore.Razor.Language public abstract string Documentation { get; set; } - public abstract ICollection AllowedChildTags { get; } - public abstract IDictionary Metadata { get; } public abstract RazorDiagnosticCollection Diagnostics { get; } + public abstract IReadOnlyList AllowedChildTags { get; } + public abstract IReadOnlyList BoundAttributes { get; } public abstract IReadOnlyList TagMatchingRules { get; } + public abstract void AllowChildTag(Action configure); + public abstract void BindAttribute(Action configure); public abstract void TagMatchingRule(Action configure); diff --git a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorComparer.cs b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorComparer.cs index b45aaa2c98..90cead0e50 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorComparer.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/TagHelperDescriptorComparer.cs @@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Razor.Language private readonly StringComparer _stringComparer; private readonly StringComparison _stringComparison; + private readonly AllowedChildTagDescriptorComparer _AllowedChildTagDescriptorComparer; private readonly BoundAttributeDescriptorComparer _boundAttributeComparer; private readonly TagMatchingRuleDescriptorComparer _tagMatchingRuleComparer; @@ -32,6 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Language { _stringComparer = StringComparer.Ordinal; _stringComparison = StringComparison.Ordinal; + _AllowedChildTagDescriptorComparer = AllowedChildTagDescriptorComparer.CaseSensitive; _boundAttributeComparer = BoundAttributeDescriptorComparer.CaseSensitive; _tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.CaseSensitive; } @@ -39,6 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Language { _stringComparer = StringComparer.OrdinalIgnoreCase; _stringComparison = StringComparison.OrdinalIgnoreCase; + _AllowedChildTagDescriptorComparer = AllowedChildTagDescriptorComparer.Default; _boundAttributeComparer = BoundAttributeDescriptorComparer.Default; _tagMatchingRuleComparer = TagMatchingRuleDescriptorComparer.Default; } @@ -71,9 +74,9 @@ namespace Microsoft.AspNetCore.Razor.Language (descriptorX.AllowedChildTags != null && descriptorY.AllowedChildTags != null && Enumerable.SequenceEqual( - descriptorX.AllowedChildTags.OrderBy(child => child, _stringComparer), - descriptorY.AllowedChildTags.OrderBy(child => child, _stringComparer), - _stringComparer))) && + descriptorX.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer), + descriptorY.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer), + _AllowedChildTagDescriptorComparer))) && string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) && string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) && string.Equals(descriptorX.TagOutputHint, descriptorY.TagOutputHint, _stringComparison) && @@ -95,6 +98,12 @@ namespace Microsoft.AspNetCore.Razor.Language hashCodeCombiner.Add(descriptor.Kind); 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); foreach (var attribute in boundAttributes) { @@ -111,15 +120,6 @@ namespace Microsoft.AspNetCore.Razor.Language hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal); 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; } } diff --git a/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorFactory.cs b/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorFactory.cs index 956c2e0c58..1913b58bfa 100644 --- a/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorFactory.cs +++ b/src/Microsoft.CodeAnalysis.Razor/DefaultTagHelperDescriptorFactory.cs @@ -141,13 +141,13 @@ namespace Microsoft.CodeAnalysis.Razor return; } - builder.AllowedChildTags.Add((string)restrictChildrenAttribute.ConstructorArguments[0].Value); + builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = (string)restrictChildrenAttribute.ConstructorArguments[0].Value); if (restrictChildrenAttribute.ConstructorArguments.Length == 2) { foreach (var value in restrictChildrenAttribute.ConstructorArguments[1].Values) { - builder.AllowedChildTags.Add((string)value.Value); + builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = (string)value.Value); } } } diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperCompletionService.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperCompletionService.cs index 4b85393079..de21ec6976 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperCompletionService.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/DefaultTagHelperCompletionService.cs @@ -244,14 +244,9 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor foreach (var descriptor in binding.Descriptors) { - if (descriptor.AllowedChildTags == null) - { - continue; - } - foreach (var childTag in descriptor.AllowedChildTags) { - var prefixedName = string.Concat(prefix, childTag); + var prefixedName = string.Concat(prefix, childTag.Name); var descriptors = _tagHelperFactsService.GetTagHelpersGivenTag( completionContext.DocumentContext, prefixedName, diff --git a/src/Microsoft.VisualStudio.LanguageServices.Razor/TagHelperDescriptorJsonConverter.cs b/src/Microsoft.VisualStudio.LanguageServices.Razor/TagHelperDescriptorJsonConverter.cs index 563060ceec..406ea9a85f 100644 --- a/src/Microsoft.VisualStudio.LanguageServices.Razor/TagHelperDescriptorJsonConverter.cs +++ b/src/Microsoft.VisualStudio.LanguageServices.Razor/TagHelperDescriptorJsonConverter.cs @@ -58,8 +58,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor foreach (var childTag in childTags) { - var tagValue = childTag.Value(); - builder.AllowedChildTags.Add(tagValue); + var tag = childTag.Value(); + builder.AllowChildTag(childTagBuilder => ReadAllowedChildTag(childTagBuilder, tag, serializer)); } 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(); + var displayName = childTag[nameof(AllowedChildTagDescriptor.DisplayName)].Value(); + var diagnostics = childTag[nameof(AllowedChildTagDescriptor.Diagnostics)].Value(); + + builder.Name = name; + builder.DisplayName = displayName; + + foreach (var diagnostic in diagnostics) + { + var diagnosticReader = diagnostic.CreateReader(); + var diagnosticObject = serializer.Deserialize(diagnosticReader); + builder.Diagnostics.Add(diagnosticObject); + } + } + private void ReadBoundAttribute(BoundAttributeDescriptorBuilder builder, JObject attribute, JsonSerializer serializer) { var descriptorKind = attribute[nameof(BoundAttributeDescriptor.Kind)].Value(); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs new file mode 100644 index 0000000000..2a6b2a8198 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs @@ -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); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs index a5a4710556..5bc81a7792 100644 --- a/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs +++ b/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language throw new ArgumentNullException(nameof(builder)); } - builder.AllowedChildTags.Add(allowedChild); + builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = allowedChild); return builder; } diff --git a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs index a5a4710556..5bc81a7792 100644 --- a/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs +++ b/test/Microsoft.VisualStudio.LanguageServices.Razor.Test/Language/TestTagHelperDescriptorBuilderExtensions.cs @@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language throw new ArgumentNullException(nameof(builder)); } - builder.AllowedChildTags.Add(allowedChild); + builder.AllowChildTag(childTagBuilder => childTagBuilder.Name = allowedChild); return builder; }