From bc33795c1c542e2e588f119e779dee443ad7e2fe Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 15 May 2023 10:39:40 -0700 Subject: [PATCH 01/10] Introduce documetnation objects for tag helpers Rather than just storing documentation strings, tag helpers objects store a "documentation object". This can be a string as before, or it can a DocumentationDescriptor object that can provide the documentation text. This has been done in a non-breaking way. --- .../src/BoundAttributeDescriptor.cs | 23 +++- .../src/BoundAttributeDescriptorBuilder.cs | 10 ++ .../src/BoundAttributeDescriptorComparer.cs | 6 +- .../src/BoundAttributeParameterDescriptor.cs | 23 +++- ...oundAttributeParameterDescriptorBuilder.cs | 11 ++ ...undAttributeParameterDescriptorComparer.cs | 6 +- .../src/ComparerUtilities.cs | 11 ++ .../src/DefaultBoundAttributeDescriptor.cs | 4 +- ...tBoundAttributeDescriptorBuilder.Policy.cs | 2 +- .../DefaultBoundAttributeDescriptorBuilder.cs | 31 ++++- ...efaultBoundAttributeParameterDescriptor.cs | 4 +- ...ributeParameterDescriptorBuilder.Policy.cs | 2 +- ...oundAttributeParameterDescriptorBuilder.cs | 31 ++++- .../src/DefaultTagHelperDescriptor.cs | 6 +- ...efaultTagHelperDescriptorBuilder.Policy.cs | 2 +- .../src/DefaultTagHelperDescriptorBuilder.cs | 33 ++++- ...mentationDescriptor.FormattedDescriptor.cs | 93 ++++++++++++++ ...ocumentationDescriptor.SimpleDescriptor.cs | 35 ++++++ .../src/DocumentationDescriptor.cs | 118 ++++++++++++++++++ .../src/DocumentationId.cs | 28 +++++ .../src/Resources.resx | 3 + .../src/TagHelperDescriptor.cs | 23 +++- .../src/TagHelperDescriptorBuilder.cs | 10 ++ .../src/TagHelperDescriptorComparer.cs | 6 +- 24 files changed, 497 insertions(+), 24 deletions(-) create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs index 8c4b128b108..5d408102c09 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs @@ -28,6 +28,7 @@ public abstract class BoundAttributeDescriptor : IEquatable (_flags & flag) != 0; private void SetFlag(int toSet) => ThreadSafeFlagOperations.Set(ref _flags, toSet); @@ -91,7 +92,27 @@ public bool HasIndexer protected set => SetOrClearFlag(HasIndexerBit, value); } - public string Documentation { get; protected set; } + public string Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + protected set => _documentationObject = value; + } + + internal object DocumentationObject + { + get => _documentationObject; + set => _documentationObject = value; + } public string DisplayName { get; protected set; } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs index 8f6d24a9fcd..dc6fce79ffc 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorBuilder.cs @@ -37,4 +37,14 @@ public abstract class BoundAttributeDescriptorBuilder public virtual void BindAttributeParameter(Action configure) { } + + internal virtual void SetDocumentation(string text) + { + throw new NotImplementedException(); + } + + internal virtual void SetDocumentation(DocumentationDescriptor documentation) + { + throw new NotImplementedException(); + } } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs index 0f86a5b6af2..6eb04f12d3e 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs @@ -44,12 +44,16 @@ public bool Equals(BoundAttributeDescriptor? descriptorX, BoundAttributeDescript descriptorX.IndexerNamePrefix != descriptorY.IndexerNamePrefix || descriptorX.TypeName != descriptorY.TypeName || descriptorX.IndexerTypeName != descriptorY.IndexerTypeName || - descriptorX.Documentation != descriptorY.Documentation || descriptorX.DisplayName != descriptorY.DisplayName) { return false; } + if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) + { + return false; + } + if (!ComparerUtilities.Equals(descriptorX.BoundAttributeParameters, descriptorY.BoundAttributeParameters, BoundAttributeParameterDescriptorComparer.Default)) { return false; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs index eda3fc6f79f..c6b0b5c9620 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs @@ -18,6 +18,7 @@ public abstract class BoundAttributeParameterDescriptor : IEquatable (_flags & flag) != 0; private void SetFlag(int toSet) => ThreadSafeFlagOperations.Set(ref _flags, toSet); @@ -53,7 +54,27 @@ public bool IsBooleanProperty public string TypeName { get; protected set; } - public string Documentation { get; protected set; } + public string Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + protected set => _documentationObject = value; + } + + internal object DocumentationObject + { + get => _documentationObject; + set => _documentationObject = value; + } public string DisplayName { get; protected set; } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorBuilder.cs index 8ef5f51dad4..d628a21a58a 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorBuilder.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Collections.Generic; namespace Microsoft.AspNetCore.Razor.Language; @@ -22,4 +23,14 @@ public abstract class BoundAttributeParameterDescriptorBuilder public abstract IDictionary Metadata { get; } public abstract RazorDiagnosticCollection Diagnostics { get; } + + internal virtual void SetDocumentation(string text) + { + throw new NotImplementedException(); + } + + internal virtual void SetDocumentation(DocumentationDescriptor documentation) + { + throw new NotImplementedException(); + } } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs index db61f4030fa..2a7cbd256c8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs @@ -38,12 +38,16 @@ public bool Equals(BoundAttributeParameterDescriptor? descriptorX, BoundAttribut descriptorX.IsEnum != descriptorY.IsEnum || descriptorX.Name != descriptorY.Name || descriptorX.TypeName != descriptorY.TypeName || - descriptorX.Documentation != descriptorY.Documentation || descriptorX.DisplayName != descriptorY.DisplayName) { return false; } + if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) + { + return false; + } + if (descriptorX.Metadata is MetadataCollection metadataX && descriptorY.Metadata is MetadataCollection metadataY && !metadataX.Equals(metadataY)) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs index 49462614043..d0b081199f8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs @@ -9,6 +9,17 @@ namespace Microsoft.AspNetCore.Razor.Language; internal static class ComparerUtilities { + public static bool AreDocumentationObjectsEqual(object? x, object? y) + { + return (x, y) switch + { + (string s1, string s2) => s1 == s2, + (DocumentationDescriptor d1, DocumentationDescriptor d2) => d1.Equals(d2), + (null, null) => true, + _ => false + }; + } + public static bool Equals(IReadOnlyList? first, IReadOnlyList? second, IEqualityComparer? comparer) { if (first == second) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs index dae0935eb1d..628dd806f89 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs @@ -13,7 +13,7 @@ public DefaultBoundAttributeDescriptor( bool hasIndexer, string? indexerNamePrefix, string? indexerTypeName, - string? documentation, + object? documentationObject, string? displayName, bool caseSensitive, bool isEditorRequired, @@ -28,7 +28,7 @@ public DefaultBoundAttributeDescriptor( HasIndexer = hasIndexer; IndexerNamePrefix = indexerNamePrefix; IndexerTypeName = indexerTypeName; - Documentation = documentation; + DocumentationObject = documentationObject; DisplayName = displayName; CaseSensitive = caseSensitive; IsEditorRequired = isEditorRequired; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs index d699831af5d..e637ac0264a 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs @@ -15,6 +15,7 @@ public override bool Return(DefaultBoundAttributeDescriptorBuilder builder) { builder._parent = null; builder._kind = null; + builder._documentationObject = null; builder.Name = null; builder.TypeName = null; @@ -23,7 +24,6 @@ public override bool Return(DefaultBoundAttributeDescriptorBuilder builder) builder.IsEditorRequired = false; builder.IndexerAttributeNamePrefix = null; builder.IndexerValueTypeName = null; - builder.Documentation = null; builder.DisplayName = null; if (builder._attributeParameterBuilders is { } attributeParameterBuilders) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs index 960cfa6fcb4..c3d98e0ec5c 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs @@ -55,6 +55,7 @@ private static readonly ObjectPool> s [AllowNull] private string _kind; private List? _attributeParameterBuilders; + private object? _documentationObject; private Dictionary? _metadata; private RazorDiagnosticCollection? _diagnostics; @@ -74,7 +75,23 @@ public DefaultBoundAttributeDescriptorBuilder(DefaultTagHelperDescriptorBuilder public override bool IsDictionary { get; set; } public override string? IndexerAttributeNamePrefix { get; set; } public override string? IndexerValueTypeName { get; set; } - public override string? Documentation { get; set; } + + public override string? Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + set => _documentationObject = value; + } + public override string? DisplayName { get; set; } public override IDictionary Metadata => _metadata ??= new Dictionary(); @@ -97,6 +114,16 @@ public override void BindAttributeParameter(Action(); @@ -116,7 +143,7 @@ public BoundAttributeDescriptor Build() IsDictionary, IndexerAttributeNamePrefix, IndexerValueTypeName, - Documentation, + _documentationObject, GetDisplayName(), CaseSensitive, IsEditorRequired, diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptor.cs index 7c66a664c96..1ae89d13b93 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptor.cs @@ -10,7 +10,7 @@ public DefaultBoundAttributeParameterDescriptor( string? name, string? typeName, bool isEnum, - string? documentation, + object? documentationObject, string? displayName, bool caseSensitive, MetadataCollection metadata, @@ -20,7 +20,7 @@ public DefaultBoundAttributeParameterDescriptor( Name = name; TypeName = typeName; IsEnum = isEnum; - Documentation = documentation; + DocumentationObject = documentationObject; DisplayName = displayName; CaseSensitive = caseSensitive; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.Policy.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.Policy.cs index 36acdd7a02c..8362c8aa184 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.Policy.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.Policy.cs @@ -15,11 +15,11 @@ public override bool Return(DefaultBoundAttributeParameterDescriptorBuilder buil { builder._parent = null; builder._kind = null; + builder._documentationObject = null; builder.Name = null; builder.TypeName = null; builder.IsEnum = false; - builder.Documentation = null; builder.DisplayName = null; ClearDiagnostics(builder._diagnostics); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.cs index 513d1f56352..112f15807d7 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeParameterDescriptorBuilder.cs @@ -30,6 +30,7 @@ public static void ReturnInstance(DefaultBoundAttributeParameterDescriptorBuilde private DefaultBoundAttributeDescriptorBuilder _parent; [AllowNull] private string _kind; + private object? _documentationObject; private Dictionary? _metadata; private RazorDiagnosticCollection? _diagnostics; @@ -47,7 +48,23 @@ public DefaultBoundAttributeParameterDescriptorBuilder(DefaultBoundAttributeDesc public override string? Name { get; set; } public override string? TypeName { get; set; } public override bool IsEnum { get; set; } - public override string? Documentation { get; set; } + + public override string? Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + set => _documentationObject = value; + } + public override string? DisplayName { get; set; } public override IDictionary Metadata => _metadata ??= new Dictionary(); @@ -56,6 +73,16 @@ public DefaultBoundAttributeParameterDescriptorBuilder(DefaultBoundAttributeDesc internal bool CaseSensitive => _parent.CaseSensitive; + internal override void SetDocumentation(string text) + { + _documentationObject = text; + } + + internal override void SetDocumentation(DocumentationDescriptor documentation) + { + _documentationObject = documentation; + } + public BoundAttributeParameterDescriptor Build() { var diagnostics = new PooledHashSet(); @@ -70,7 +97,7 @@ public BoundAttributeParameterDescriptor Build() Name, TypeName, IsEnum, - Documentation, + _documentationObject, GetDisplayName(), CaseSensitive, MetadataCollection.CreateOrEmpty(_metadata), diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs index 3c0297d2faa..ea198f53441 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Immutable; - namespace Microsoft.AspNetCore.Razor.Language; internal class DefaultTagHelperDescriptor : TagHelperDescriptor @@ -12,7 +10,7 @@ public DefaultTagHelperDescriptor( string name, string assemblyName, string displayName, - string? documentation, + object? documentationObject, string? tagOutputHint, bool caseSensitive, TagMatchingRuleDescriptor[] tagMatchingRules, @@ -25,7 +23,7 @@ public DefaultTagHelperDescriptor( Name = name; AssemblyName = assemblyName; DisplayName = displayName; - Documentation = documentation; + DocumentationObject = documentationObject; TagOutputHint = tagOutputHint; CaseSensitive = caseSensitive; TagMatchingRules = tagMatchingRules; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs index 86e3b6886a6..0dfc8426d79 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs @@ -16,11 +16,11 @@ public override bool Return(DefaultTagHelperDescriptorBuilder builder) builder._kind = null; builder._name = null; builder._assemblyName = null; + builder._documentationObject = null; builder.DisplayName = null; builder.TagOutputHint = null; builder.CaseSensitive = false; - builder.Documentation = null; if (builder._allowedChildTags is { } allowedChildTagBuilders) { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs index 530d0b25d78..b4aa296e4eb 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs @@ -45,6 +45,8 @@ private static readonly ObjectPool> s_tagMatc private string? _name; private string? _assemblyName; + private object? _documentationObject; + private List? _allowedChildTags; private List? _attributeBuilders; private List? _tagMatchingRuleBuilders; @@ -72,7 +74,22 @@ public DefaultTagHelperDescriptorBuilder(string kind, string name, string assemb public override string? DisplayName { get; set; } public override string? TagOutputHint { get; set; } public override bool CaseSensitive { get; set; } - public override string? Documentation { get; set; } + + public override string? Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + set => _documentationObject = value; + } public override IDictionary Metadata => _metadata; public override RazorDiagnosticCollection Diagnostics => _diagnostics ??= new RazorDiagnosticCollection(); @@ -149,6 +166,16 @@ public override void TagMatchingRule(Action co _tagMatchingRuleBuilders.Add(builder); } + internal override void SetDocumentation(string text) + { + _documentationObject = text; + } + + internal override void SetDocumentation(DocumentationDescriptor documentation) + { + _documentationObject = documentation; + } + public override TagHelperDescriptor Build() { using var diagnostics = new PooledHashSet(); @@ -164,7 +191,7 @@ public override TagHelperDescriptor Build() Name, AssemblyName, GetDisplayName(), - Documentation, + _documentationObject, TagOutputHint, CaseSensitive, tagMatchingRules, @@ -178,7 +205,7 @@ public override TagHelperDescriptor Build() public override void Reset() { - Documentation = null; + _documentationObject = null; TagOutputHint = null; _allowedChildTags?.Clear(); _attributeBuilders?.Clear(); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs new file mode 100644 index 00000000000..256a5ee71e7 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Globalization; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language; + +internal abstract partial class DocumentationDescriptor +{ + private sealed class FormattedDescriptor : DocumentationDescriptor + { + public override object?[] Args { get; } + + private string? _formattedString; + + public FormattedDescriptor(DocumentationId id, object?[] args) + : base(id) + { +#if DEBUG + foreach (var arg in args) + { + Debug.Assert( + arg is string || arg is int || arg is bool || arg is null, + "Only string, int, bool, or null arguments are allowed."); + } +#endif + + Args = args; + } + + public override string GetText() + => _formattedString ??= string.Format(CultureInfo.CurrentCulture, GetDocumentationText(), Args); + + public override bool Equals(DocumentationDescriptor other) + { + if (other is not FormattedDescriptor { Id: var id, Args: var args }) + { + return false; + } + + if (Id != id) + { + return false; + } + + var length = Args.Length; + + if (length != args.Length) + { + return false; + } + + for (var i = 0; i < length; i++) + { + var thisArg = Args[i]; + var otherArg = args[i]; + + var areEqual = (thisArg, otherArg) switch + { + (string s1, string s2) => s1 == s2, + (int i1, int i2) => i1 == i2, + (bool b1, bool b2) => b1 == b2, + (object o1, object o2) => Equals(o1, o2), + (null, null) => true, + _ => false + }; + + if (!areEqual) + { + return false; + } + } + + return true; + } + + protected override int ComputeHashCode() + { + var result = HashCodeCombiner.Start(); + + result.Add((int)Id); + + foreach (var arg in Args) + { + result.Add(arg); + } + + return result.CombinedHash; + } + } +} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs new file mode 100644 index 00000000000..b15ed62ef01 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Microsoft.Extensions.Internal; + +namespace Microsoft.AspNetCore.Razor.Language; + +internal abstract partial class DocumentationDescriptor +{ + private sealed class SimpleDescriptor : DocumentationDescriptor + { + public override object?[] Args => Array.Empty(); + + public SimpleDescriptor(DocumentationId id) + : base(id) + { + } + + public override string GetText() + => GetDocumentationText(); + + public override bool Equals(DocumentationDescriptor other) + => other is SimpleDescriptor { Id: var id } && Id == id; + + protected override int ComputeHashCode() + { + var result = HashCodeCombiner.Start(); + + result.Add((int)Id); + + return result.CombinedHash; + } + } +} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs new file mode 100644 index 00000000000..bb7d0403290 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs @@ -0,0 +1,118 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.AspNetCore.Razor.Language; + +internal abstract partial class DocumentationDescriptor : IEquatable +{ + public static readonly DocumentationDescriptor BindTagHelper_Fallback = new SimpleDescriptor(DocumentationId.BindTagHelper_Fallback); + public static readonly DocumentationDescriptor BindTagHelper_Fallback_Event = new SimpleDescriptor(DocumentationId.BindTagHelper_Fallback_Event); + public static readonly DocumentationDescriptor BindTagHelper_Fallback_Format = new SimpleDescriptor(DocumentationId.BindTagHelper_Fallback_Format); + public static readonly DocumentationDescriptor BindTagHelper_Element = new SimpleDescriptor(DocumentationId.BindTagHelper_Element); + public static readonly DocumentationDescriptor BindTagHelper_Element_After = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_After); + public static readonly DocumentationDescriptor BindTagHelper_Element_Culture = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_Culture); + public static readonly DocumentationDescriptor BindTagHelper_Element_Event = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_Event); + public static readonly DocumentationDescriptor BindTagHelper_Element_Format = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_Format); + public static readonly DocumentationDescriptor BindTagHelper_Element_Get = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_Get); + public static readonly DocumentationDescriptor BindTagHelper_Element_Set = new SimpleDescriptor(DocumentationId.BindTagHelper_Element_Set); + public static readonly DocumentationDescriptor BindTagHelper_Component = new SimpleDescriptor(DocumentationId.BindTagHelper_Component); + public static readonly DocumentationDescriptor ChildContentParameterName = new SimpleDescriptor(DocumentationId.ChildContentParameterName); + public static readonly DocumentationDescriptor ChildContentParameterName_TopLevel = new SimpleDescriptor(DocumentationId.ChildContentParameterName_TopLevel); + public static readonly DocumentationDescriptor ComponentTypeParameter = new SimpleDescriptor(DocumentationId.ComponentTypeParameter); + public static readonly DocumentationDescriptor EventHandlerTagHelper = new SimpleDescriptor(DocumentationId.EventHandlerTagHelper); + public static readonly DocumentationDescriptor EventHandlerTagHelper_PreventDefault = new SimpleDescriptor(DocumentationId.EventHandlerTagHelper_PreventDefault); + public static readonly DocumentationDescriptor EventHandlerTagHelper_StopPropagation = new SimpleDescriptor(DocumentationId.EventHandlerTagHelper_StopPropagation); + public static readonly DocumentationDescriptor KeyTagHelper = new SimpleDescriptor(DocumentationId.KeyTagHelper); + public static readonly DocumentationDescriptor RefTagHelper = new SimpleDescriptor(DocumentationId.RefTagHelper); + public static readonly DocumentationDescriptor SplatTagHelper = new SimpleDescriptor(DocumentationId.SplatTagHelper); + + public static DocumentationDescriptor Format(DocumentationId id, params object?[] args) + => new FormattedDescriptor(id, args); + + public static DocumentationDescriptor From(DocumentationId id, params object?[]? args) + { + if (args is null or { Length: 0 }) + { + return id switch + { + DocumentationId.BindTagHelper_Fallback => BindTagHelper_Fallback, + DocumentationId.BindTagHelper_Fallback_Event => BindTagHelper_Fallback_Event, + DocumentationId.BindTagHelper_Fallback_Format => BindTagHelper_Fallback_Format, + DocumentationId.BindTagHelper_Element => BindTagHelper_Element, + DocumentationId.BindTagHelper_Element_After => BindTagHelper_Element_After, + DocumentationId.BindTagHelper_Element_Culture => BindTagHelper_Element_Culture, + DocumentationId.BindTagHelper_Element_Event => BindTagHelper_Element_Event, + DocumentationId.BindTagHelper_Element_Format => BindTagHelper_Element_Format, + DocumentationId.BindTagHelper_Element_Get => BindTagHelper_Element_Get, + DocumentationId.BindTagHelper_Element_Set => BindTagHelper_Element_Set, + DocumentationId.BindTagHelper_Component => BindTagHelper_Component, + DocumentationId.ChildContentParameterName => ChildContentParameterName, + DocumentationId.ChildContentParameterName_TopLevel => ChildContentParameterName_TopLevel, + DocumentationId.ComponentTypeParameter => ComponentTypeParameter, + DocumentationId.EventHandlerTagHelper => EventHandlerTagHelper, + DocumentationId.EventHandlerTagHelper_PreventDefault => EventHandlerTagHelper_PreventDefault, + DocumentationId.EventHandlerTagHelper_StopPropagation => EventHandlerTagHelper_StopPropagation, + DocumentationId.KeyTagHelper => KeyTagHelper, + DocumentationId.RefTagHelper => RefTagHelper, + DocumentationId.SplatTagHelper => SplatTagHelper, + + _ => throw new NotSupportedException(Resources.FormatUnknown_documentation_id_0(id)) + }; + } + + return Format(id, args); + } + + public DocumentationId Id { get; } + public abstract object?[] Args { get; } + + private int? _hashCode; + + private protected DocumentationDescriptor(DocumentationId id) + { + Id = id; + } + + public sealed override bool Equals(object obj) + => obj is DocumentationDescriptor other && Equals(other); + + public abstract bool Equals(DocumentationDescriptor other); + + public sealed override int GetHashCode() + => _hashCode ??= ComputeHashCode(); + + protected abstract int ComputeHashCode(); + + public abstract string GetText(); + + private string GetDocumentationText() + { + return Id switch + { + DocumentationId.BindTagHelper_Fallback => ComponentResources.BindTagHelper_Fallback_Documentation, + DocumentationId.BindTagHelper_Fallback_Event => ComponentResources.BindTagHelper_Fallback_Event_Documentation, + DocumentationId.BindTagHelper_Fallback_Format => ComponentResources.BindTagHelper_Fallback_Format_Documentation, + DocumentationId.BindTagHelper_Element => ComponentResources.BindTagHelper_Element_Documentation, + DocumentationId.BindTagHelper_Element_After => ComponentResources.BindTagHelper_Element_After_Documentation, + DocumentationId.BindTagHelper_Element_Culture => ComponentResources.BindTagHelper_Element_Culture_Documentation, + DocumentationId.BindTagHelper_Element_Event => ComponentResources.BindTagHelper_Element_Event_Documentation, + DocumentationId.BindTagHelper_Element_Format => ComponentResources.BindTagHelper_Element_Format_Documentation, + DocumentationId.BindTagHelper_Element_Get => ComponentResources.BindTagHelper_Element_Get_Documentation, + DocumentationId.BindTagHelper_Element_Set => ComponentResources.BindTagHelper_Element_Set_Documentation, + DocumentationId.BindTagHelper_Component => ComponentResources.BindTagHelper_Component_Documentation, + DocumentationId.ChildContentParameterName => ComponentResources.ChildContentParameterName_Documentation, + DocumentationId.ChildContentParameterName_TopLevel => ComponentResources.ChildContentParameterName_TopLevelDocumentation, + DocumentationId.ComponentTypeParameter => ComponentResources.ComponentTypeParameter_Documentation, + DocumentationId.EventHandlerTagHelper => ComponentResources.EventHandlerTagHelper_Documentation, + DocumentationId.EventHandlerTagHelper_PreventDefault => ComponentResources.EventHandlerTagHelper_PreventDefault_Documentation, + DocumentationId.EventHandlerTagHelper_StopPropagation => ComponentResources.EventHandlerTagHelper_StopPropagation_Documentation, + DocumentationId.KeyTagHelper => ComponentResources.KeyTagHelper_Documentation, + DocumentationId.RefTagHelper => ComponentResources.RefTagHelper_Documentation, + DocumentationId.SplatTagHelper => ComponentResources.SplatTagHelper_Documentation, + + var id => throw new NotSupportedException(Resources.FormatUnknown_documentation_id_0(id)) + }; + } +} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs new file mode 100644 index 00000000000..fceb2e1f32f --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Razor.Language; + +internal enum DocumentationId +{ + BindTagHelper_Fallback, + BindTagHelper_Fallback_Event, + BindTagHelper_Fallback_Format, + BindTagHelper_Element, + BindTagHelper_Element_After, + BindTagHelper_Element_Culture, + BindTagHelper_Element_Event, + BindTagHelper_Element_Format, + BindTagHelper_Element_Get, + BindTagHelper_Element_Set, + BindTagHelper_Component, + ChildContentParameterName, + ChildContentParameterName_TopLevel, + ComponentTypeParameter, + EventHandlerTagHelper, + EventHandlerTagHelper_PreventDefault, + EventHandlerTagHelper_StopPropagation, + KeyTagHelper, + RefTagHelper, + SplatTagHelper, +} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx index f191e7afce5..fbf2cc2b34d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx @@ -583,4 +583,7 @@ The given key '{0}' was not present. + + Unknown documentation id: '{0}'. + \ No newline at end of file diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs index aef41d462f6..78a158b3992 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs @@ -23,6 +23,7 @@ public abstract class TagHelperDescriptor : IEquatable private int _flags; private int? _hashCode; + private object _documentationObject; private IEnumerable _allDiagnostics; private BoundAttributeDescriptor[] _editorRequiredAttributes; @@ -49,7 +50,27 @@ protected TagHelperDescriptor(string kind) public IReadOnlyList AllowedChildTags { get; protected set; } - public string Documentation { get; protected set; } + public string Documentation + { + get + { + return _documentationObject switch + { + string s => s, + DocumentationDescriptor d => d.GetText(), + null => null, + _ => throw new NotSupportedException() + }; + } + + protected set => _documentationObject = value; + } + + internal object DocumentationObject + { + get => _documentationObject; + set => _documentationObject = value; + } public string DisplayName { get; protected set; } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilder.cs index ed0e71a3e40..af05251b50b 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorBuilder.cs @@ -124,4 +124,14 @@ public static PooledBuilder GetPooledInstance( public abstract TagHelperDescriptor Build(); public abstract void Reset(); + + internal virtual void SetDocumentation(string text) + { + throw new NotImplementedException(); + } + + internal virtual void SetDocumentation(DocumentationDescriptor documentation) + { + throw new NotImplementedException(); + } } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs index 9d8a15e0681..43f5e61648e 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs @@ -34,13 +34,17 @@ public bool Equals(TagHelperDescriptor? descriptorX, TagHelperDescriptor? descri descriptorX.AssemblyName != descriptorY.AssemblyName || descriptorX.Name != descriptorY.Name || descriptorX.CaseSensitive != descriptorY.CaseSensitive || - descriptorX.Documentation != descriptorY.Documentation || descriptorX.DisplayName != descriptorY.DisplayName || descriptorX.TagOutputHint != descriptorY.TagOutputHint) { return false; } + if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) + { + return false; + } + if (!ComparerUtilities.Equals(descriptorX.BoundAttributes, descriptorY.BoundAttributes, BoundAttributeDescriptorComparer.Default) || !ComparerUtilities.Equals(descriptorX.TagMatchingRules, descriptorY.TagMatchingRules, TagMatchingRuleDescriptorComparer.Default) || !ComparerUtilities.Equals(descriptorX.AllowedChildTags, descriptorY.AllowedChildTags, AllowedChildTagDescriptorComparer.Default) || From 7c2e7ad072fa37dbac667863fee1b2a3e972d33c Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 15 May 2023 11:38:15 -0700 Subject: [PATCH 02/10] Update compiler to use tag helper documentation objects The compiler no longer sets the Documentation property of any tag helper objects that it creates. Instead, it specifies particular DocumentationDescriptors. This avoids formatting strings in the compiler that it doesn't actually use. --- .../src/BindTagHelperDescriptorProvider.cs | 87 +++++++++++-------- .../ComponentTagHelperDescriptorProvider.cs | 20 +++-- .../src/DefaultTagHelperDescriptorFactory.cs | 4 +- ...EventHandlerTagHelperDescriptorProvider.cs | 32 ++++--- .../src/KeyTagHelperDescriptorProvider.cs | 4 +- .../src/RefTagHelperDescriptorProvider.cs | 4 +- .../src/SplatTagHelperDescriptorProvider.cs | 4 +- .../TagHelperDescriptorJsonConverter.cs | 6 +- ...estTagHelperDescriptorBuilderExtensions.cs | 2 +- 9 files changed, 92 insertions(+), 71 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs index 0f0b5762c0e..d6a9e020c9a 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs @@ -146,7 +146,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() out var builder); builder.CaseSensitive = true; - builder.Documentation = ComponentResources.BindTagHelper_Fallback_Documentation; + builder.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Bind.TagHelperKind); builder.Metadata.Add(TagHelperMetadata.Common.ClassifyAttributesOnly, bool.TrueString); @@ -173,7 +173,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() builder.BindAttribute(attribute => { attribute.Metadata[ComponentMetadata.Common.DirectiveAttribute] = bool.TrueString; - attribute.Documentation = ComponentResources.BindTagHelper_Fallback_Documentation; + attribute.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback); var attributeName = "@bind-..."; attribute.Name = attributeName; @@ -188,7 +188,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "format"; parameter.TypeName = typeof(string).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Fallback_Format_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback_Format); parameter.SetPropertyName("Format"); }); @@ -197,7 +197,9 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "event"; parameter.TypeName = typeof(string).FullName; - parameter.Documentation = string.Format(CultureInfo.CurrentCulture, ComponentResources.BindTagHelper_Fallback_Event_Documentation, attributeName); + parameter.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Fallback_Event, attributeName)); parameter.SetPropertyName("Event"); }); @@ -206,7 +208,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "culture"; parameter.TypeName = typeof(CultureInfo).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Culture_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture); parameter.SetPropertyName("Culture"); }); @@ -215,7 +217,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "get"; parameter.TypeName = typeof(object).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Get_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get); parameter.SetPropertyName("Get"); @@ -226,7 +228,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "set"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Set_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set); parameter.SetPropertyName("Set"); }); @@ -235,7 +237,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() { parameter.Name = "after"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_After_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After); parameter.SetPropertyName("After"); }); @@ -381,11 +383,11 @@ private static ImmutableArray CreateElementBindTagHelpers(I out var builder); builder.CaseSensitive = true; - builder.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.BindTagHelper_Element_Documentation, - entry.ValueAttribute, - entry.ChangeAttribute); + builder.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Element, + entry.ValueAttribute, + entry.ChangeAttribute)); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Bind.TagHelperKind); builder.Metadata.Add(TagHelperMetadata.Common.ClassifyAttributesOnly, bool.TrueString); @@ -469,11 +471,11 @@ private static ImmutableArray CreateElementBindTagHelpers(I builder.BindAttribute(a => { a.Metadata[ComponentMetadata.Common.DirectiveAttribute] = bool.TrueString; - a.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.BindTagHelper_Element_Documentation, - entry.ValueAttribute, - entry.ChangeAttribute); + a.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Element, + entry.ValueAttribute, + entry.ChangeAttribute)); a.Name = attributeName; a.TypeName = typeof(object).FullName; @@ -486,7 +488,10 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "format"; parameter.TypeName = typeof(string).FullName; - parameter.Documentation = string.Format(CultureInfo.CurrentCulture, ComponentResources.BindTagHelper_Element_Format_Documentation, attributeName); + parameter.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Element_Format, + attributeName)); parameter.SetPropertyName(formatName); }); @@ -495,7 +500,10 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "event"; parameter.TypeName = typeof(string).FullName; - parameter.Documentation = string.Format(CultureInfo.CurrentCulture, ComponentResources.BindTagHelper_Element_Event_Documentation, attributeName); + parameter.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Element_Event, + attributeName)); parameter.SetPropertyName(eventName); }); @@ -504,7 +512,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "culture"; parameter.TypeName = typeof(CultureInfo).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Culture_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture); parameter.SetPropertyName("Culture"); }); @@ -513,7 +521,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "get"; parameter.TypeName = typeof(object).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Get_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get); parameter.SetPropertyName("Get"); parameter.SetBindAttributeGetSet(); @@ -523,7 +531,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "set"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Set_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set); parameter.SetPropertyName("Set"); }); @@ -532,7 +540,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I { parameter.Name = "after"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_After_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After); parameter.SetPropertyName("After"); }); @@ -543,7 +551,10 @@ private static ImmutableArray CreateElementBindTagHelpers(I { attribute.Name = formatAttributeName; attribute.TypeName = "System.String"; - attribute.Documentation = string.Format(CultureInfo.CurrentCulture, ComponentResources.BindTagHelper_Element_Format_Documentation, attributeName); + attribute.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Element_Format, + attributeName)); // WTE has a bug 15.7p1 where a Tag Helper without a display-name that looks like // a C# property will crash trying to create the toolips. @@ -623,11 +634,11 @@ private static ImmutableArray CreateComponentBindTagHelpers builder.DisplayName = tagHelper.DisplayName; builder.CaseSensitive = true; - builder.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.BindTagHelper_Component_Documentation, - valueAttribute.Name, - changeAttribute.Name); + builder.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Component, + valueAttribute.Name, + changeAttribute.Name)); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Bind.TagHelperKind); builder.Metadata[TagHelperMetadata.Runtime.Name] = ComponentMetadata.Bind.RuntimeName; @@ -677,11 +688,11 @@ private static ImmutableArray CreateComponentBindTagHelpers builder.BindAttribute(attribute => { attribute.Metadata[ComponentMetadata.Common.DirectiveAttribute] = bool.TrueString; - attribute.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.BindTagHelper_Component_Documentation, - valueAttribute.Name, - changeAttribute.Name); + attribute.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.BindTagHelper_Component, + valueAttribute.Name, + changeAttribute.Name)); attribute.Name = "@bind-" + valueAttribute.Name; attribute.TypeName = changeAttribute.TypeName; @@ -695,7 +706,7 @@ private static ImmutableArray CreateComponentBindTagHelpers { parameter.Name = "get"; parameter.TypeName = typeof(object).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Get_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get); parameter.SetPropertyName("Get"); parameter.SetBindAttributeGetSet(); @@ -705,7 +716,7 @@ private static ImmutableArray CreateComponentBindTagHelpers { parameter.Name = "set"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_Set_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set); parameter.SetPropertyName("Set"); }); @@ -714,7 +725,7 @@ private static ImmutableArray CreateComponentBindTagHelpers { parameter.Name = "after"; parameter.TypeName = typeof(Delegate).FullName; - parameter.Documentation = ComponentResources.BindTagHelper_Element_After_Documentation; + parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After); parameter.SetPropertyName("After"); }); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs index 9b100583327..68052369df0 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs @@ -165,7 +165,7 @@ private static TagHelperDescriptorBuilder.PooledBuilder GetPooledTagHelperDescri var xml = type.GetDocumentationCommentXml(); if (!string.IsNullOrEmpty(xml)) { - builder.Documentation = xml; + builder.SetDocumentation(xml); } foreach (var (property, kind) in properties) @@ -233,7 +233,7 @@ private static void CreateProperty(TagHelperDescriptorBuilder builder, IProperty var xml = property.GetDocumentationCommentXml(); if (!string.IsNullOrEmpty(xml)) { - pb.Documentation = xml; + pb.SetDocumentation(xml); } }); @@ -440,7 +440,11 @@ private static void CreateTypeParameterProperty(TagHelperDescriptorBuilder build pb.Metadata[ComponentMetadata.Component.TypeParameterConstraintsKey] = whereClauseText; } - pb.Documentation = string.Format(CultureInfo.InvariantCulture, ComponentResources.ComponentTypeParameter_Documentation, typeParameter.Name, builder.Name); + pb.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.ComponentTypeParameter, + typeParameter.Name, + builder.Name)); }); static bool TryGetWhereClauseText(ITypeParameterSymbol typeParameter, PooledList constraints, [NotNullWhen(true)] out string constraintsText) @@ -502,7 +506,7 @@ private static TagHelperDescriptor CreateChildContentDescriptor(TagHelperDescrip var xml = attribute.Documentation; if (!string.IsNullOrEmpty(xml)) { - builder.Documentation = xml; + builder.SetDocumentation(xml); } // Child content matches the property name, but only as a direct child of the component. @@ -538,9 +542,11 @@ private static void CreateContextParameter(TagHelperDescriptorBuilder builder, s b.Metadata.Add(ComponentMetadata.Component.ChildContentParameterNameKey, bool.TrueString); b.Metadata.Add(TagHelperMetadata.Common.PropertyName, b.Name); - b.Documentation = childContentName == null - ? ComponentResources.ChildContentParameterName_TopLevelDocumentation - : string.Format(CultureInfo.InvariantCulture, ComponentResources.ChildContentParameterName_Documentation, childContentName); + var documentation = childContentName == null + ? DocumentationDescriptor.ChildContentParameterName_TopLevel + : DocumentationDescriptor.Format(DocumentationId.ChildContentParameterName, childContentName); + + b.SetDocumentation(documentation); }); } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorFactory.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorFactory.cs index 6e8f15dac79..bcdb77f7459 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorFactory.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/DefaultTagHelperDescriptorFactory.cs @@ -162,7 +162,7 @@ private void AddDocumentation(INamedTypeSymbol type, TagHelperDescriptorBuilder if (!string.IsNullOrEmpty(xml)) { - builder.Documentation = xml; + builder.SetDocumentation(xml); } } @@ -221,7 +221,7 @@ private void ConfigureBoundAttribute( if (!string.IsNullOrEmpty(xml)) { - builder.Documentation = xml; + builder.SetDocumentation(xml); } } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs index ca547b408b7..49639149cc9 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs @@ -144,11 +144,11 @@ private static ImmutableArray CreateEventHandlerTagHelpers( out var builder); builder.CaseSensitive = true; - builder.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.EventHandlerTagHelper_Documentation, - attributeName, - eventArgType); + builder.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.EventHandlerTagHelper, + attributeName, + eventArgType)); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.EventHandler.TagHelperKind); builder.Metadata.Add(ComponentMetadata.EventHandler.EventArgsType, eventArgType); @@ -205,11 +205,11 @@ private static ImmutableArray CreateEventHandlerTagHelpers( builder.BindAttribute(a => { - a.Documentation = string.Format( - CultureInfo.CurrentCulture, - ComponentResources.EventHandlerTagHelper_Documentation, - attributeName, - eventArgType); + a.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.EventHandlerTagHelper, + attributeName, + eventArgType)); a.Name = attributeName; @@ -232,8 +232,10 @@ private static ImmutableArray CreateEventHandlerTagHelpers( { parameter.Name = "preventDefault"; parameter.TypeName = typeof(bool).FullName; - parameter.Documentation = string.Format( - CultureInfo.CurrentCulture, ComponentResources.EventHandlerTagHelper_PreventDefault_Documentation, attributeName); + parameter.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.EventHandlerTagHelper_PreventDefault, + attributeName)); parameter.SetPropertyName("PreventDefault"); }); @@ -245,8 +247,10 @@ private static ImmutableArray CreateEventHandlerTagHelpers( { parameter.Name = "stopPropagation"; parameter.TypeName = typeof(bool).FullName; - parameter.Documentation = string.Format( - CultureInfo.CurrentCulture, ComponentResources.EventHandlerTagHelper_StopPropagation_Documentation, attributeName); + parameter.SetDocumentation( + DocumentationDescriptor.Format( + DocumentationId.EventHandlerTagHelper_StopPropagation, + attributeName)); parameter.SetPropertyName("StopPropagation"); }); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs index a1e315b4cbc..5ab6838b23d 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/KeyTagHelperDescriptorProvider.cs @@ -59,7 +59,7 @@ static TagHelperDescriptor CreateKeyTagHelper() out var builder); builder.CaseSensitive = true; - builder.Documentation = ComponentResources.KeyTagHelper_Documentation; + builder.SetDocumentation(DocumentationDescriptor.KeyTagHelper); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Key.TagHelperKind); builder.Metadata.Add(TagHelperMetadata.Common.ClassifyAttributesOnly, bool.TrueString); @@ -81,7 +81,7 @@ static TagHelperDescriptor CreateKeyTagHelper() builder.BindAttribute(attribute => { - attribute.Documentation = ComponentResources.KeyTagHelper_Documentation; + attribute.SetDocumentation(DocumentationDescriptor.KeyTagHelper); attribute.Name = "@key"; // WTE has a bug 15.7p1 where a Tag Helper without a display-name that looks like diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs index 029821dabaa..ba87ef24c38 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/RefTagHelperDescriptorProvider.cs @@ -59,7 +59,7 @@ static TagHelperDescriptor CreateRefTagHelper() out var builder); builder.CaseSensitive = true; - builder.Documentation = ComponentResources.RefTagHelper_Documentation; + builder.SetDocumentation(DocumentationDescriptor.RefTagHelper); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Ref.TagHelperKind); builder.Metadata.Add(TagHelperMetadata.Common.ClassifyAttributesOnly, bool.TrueString); @@ -81,7 +81,7 @@ static TagHelperDescriptor CreateRefTagHelper() builder.BindAttribute(attribute => { - attribute.Documentation = ComponentResources.RefTagHelper_Documentation; + attribute.SetDocumentation(DocumentationDescriptor.RefTagHelper); attribute.Name = "@ref"; // WTE has a bug 15.7p1 where a Tag Helper without a display-name that looks like diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs index 995f6183189..a11a427dd2c 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/SplatTagHelperDescriptorProvider.cs @@ -59,7 +59,7 @@ static TagHelperDescriptor CreateSplatTagHelper() out var builder); builder.CaseSensitive = true; - builder.Documentation = ComponentResources.SplatTagHelper_Documentation; + builder.SetDocumentation(DocumentationDescriptor.SplatTagHelper); builder.Metadata.Add(ComponentMetadata.SpecialKindKey, ComponentMetadata.Splat.TagHelperKind); builder.Metadata.Add(TagHelperMetadata.Common.ClassifyAttributesOnly, bool.TrueString); @@ -81,7 +81,7 @@ static TagHelperDescriptor CreateSplatTagHelper() builder.BindAttribute(attribute => { - attribute.Documentation = ComponentResources.SplatTagHelper_Documentation; + attribute.SetDocumentation(DocumentationDescriptor.SplatTagHelper); attribute.Name = "@attributes"; // WTE has a bug 15.7p1 where a Tag Helper without a display-name that looks like diff --git a/src/Compiler/shared/TagHelperDescriptorJsonConverter.cs b/src/Compiler/shared/TagHelperDescriptorJsonConverter.cs index 20cf463385a..7a9c470108d 100644 --- a/src/Compiler/shared/TagHelperDescriptorJsonConverter.cs +++ b/src/Compiler/shared/TagHelperDescriptorJsonConverter.cs @@ -40,7 +40,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist if (reader.Read()) { var documentation = (string)reader.Value; - builder.Documentation = documentation; + builder.SetDocumentation(documentation); } break; case nameof(TagHelperDescriptor.TagOutputHint): @@ -410,7 +410,7 @@ private static void ReadBoundAttribute(JsonReader reader, TagHelperDescriptorBui if (reader.Read()) { var documentation = (string)reader.Value; - attribute.Documentation = documentation; + attribute.SetDocumentation(documentation); } break; case nameof(BoundAttributeDescriptor.IndexerNamePrefix): @@ -524,7 +524,7 @@ private static void ReadBoundAttributeParameter(JsonReader reader, BoundAttribut if (reader.Read()) { var documentation = (string)reader.Value; - parameter.Documentation = documentation; + parameter.SetDocumentation(documentation); } break; case nameof(BoundAttributeParameterDescriptor.Metadata): diff --git a/src/Compiler/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs b/src/Compiler/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs index 20c9b5c9064..da7836f43be 100644 --- a/src/Compiler/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs +++ b/src/Compiler/test/Microsoft.AspNetCore.Razor.Test.Common/Language/TestTagHelperDescriptorBuilderExtensions.cs @@ -76,7 +76,7 @@ public static TagHelperDescriptorBuilder Documentation(this TagHelperDescriptorB throw new ArgumentNullException(nameof(builder)); } - builder.Documentation = documentation; + builder.SetDocumentation(documentation); return builder; } From 5b4340861d4d87a39bb3076d6cbc4b7660b8052e Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 15 May 2023 12:14:17 -0700 Subject: [PATCH 03/10] Update tooling JSON.NET converters to handle documentation objects --- .../Resources/SR.resx | 3 ++ .../Resources/xlf/SR.cs.xlf | 5 +++ .../Resources/xlf/SR.de.xlf | 5 +++ .../Resources/xlf/SR.es.xlf | 5 +++ .../Resources/xlf/SR.fr.xlf | 5 +++ .../Resources/xlf/SR.it.xlf | 5 +++ .../Resources/xlf/SR.ja.xlf | 5 +++ .../Resources/xlf/SR.ko.xlf | 5 +++ .../Resources/xlf/SR.pl.xlf | 5 +++ .../Resources/xlf/SR.pt-BR.xlf | 5 +++ .../Resources/xlf/SR.ru.xlf | 5 +++ .../Resources/xlf/SR.tr.xlf | 5 +++ .../Resources/xlf/SR.zh-Hans.xlf | 5 +++ .../Resources/xlf/SR.zh-Hant.xlf | 5 +++ .../Serialization/JsonDataReader.cs | 19 +++++++++ .../Serialization/JsonDataWriter.cs | 40 +++++++++++++++++++ ...ctReaders.BoundAttributeParameterReader.cs | 13 +++++- .../ObjectReaders.BoundAttributeReader.cs | 13 +++++- .../ObjectReaders.TagHelperReader.cs | 13 +++++- .../Serialization/ObjectReaders.cs | 21 ++++++++++ .../Serialization/ObjectWriters.cs | 32 +++++++++++++-- 21 files changed, 213 insertions(+), 6 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/SR.resx b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/SR.resx index 09302fc18b4..33722a23b8e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/SR.resx +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/SR.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Could not read value - JSON token was '{0}'. + Encountered end of stream before end of object. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.cs.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.cs.xlf index 54bd65f21c3..b9041ee9f06 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.cs.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.cs.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Došlo k ukončení datového proudu před dokončením objektu. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.de.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.de.xlf index f4403c8b7e5..ec07ed57fb5 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.de.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.de.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Encountered end of stream before end of object. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.es.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.es.xlf index 998312a2411..25d036941a4 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.es.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.es.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Se encontró el final de la secuencia antes del final del objeto. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.fr.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.fr.xlf index f75753104a1..901534de642 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.fr.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.fr.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Fin de flux rencontrée avant la fin de l’objet. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.it.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.it.xlf index c6d3ea8eb6d..4fa06ac4260 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.it.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.it.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. È stata rilevata fine del flusso prima della fine dell'oggetto. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ja.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ja.xlf index dd65e2b2881..db5f0d6a1d8 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ja.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ja.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. オブジェクトの終わりの前にストリームの終わりが見つかりました。 diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ko.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ko.xlf index bdcd7dc315b..84504470d4e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ko.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ko.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. 개체의 끝 전에 스트림의 끝이 발견되었습니다. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pl.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pl.xlf index a2593ab378b..52e5c1d5dea 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pl.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pl.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Napotkano koniec strumienia przed końcem obiektu. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pt-BR.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pt-BR.xlf index c017bebaee3..455da1053c7 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pt-BR.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.pt-BR.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Fim de fluxo encontrado antes do fim do objeto. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ru.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ru.xlf index 4dec7a513ad..155480e00e5 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ru.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.ru.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Обнаружен конец потока перед концом объекта. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.tr.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.tr.xlf index 3e89e2bd6e4..71cdccf3aa0 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.tr.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.tr.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. Nesne sonundan önce akış sonuyla karşılaşıldı. diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hans.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hans.xlf index 415f74acc1b..f095bbcaadb 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hans.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. 在对象结尾之前遇到流结尾。 diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hant.xlf b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hant.xlf index 7d187e69115..8976c1584a8 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Resources/xlf/SR.zh-Hant.xlf @@ -2,6 +2,11 @@ + + Could not read value - JSON token was '{0}'. + Could not read value - JSON token was '{0}'. + + Encountered end of stream before end of object. 在物件結尾之前發現資料流結尾。 diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataReader.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataReader.cs index eaab1b2623d..5ffbe5553f8 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataReader.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataReader.cs @@ -230,6 +230,25 @@ public string ReadNonNullString(string propertyName) return ReadNonNullString(); } + public object? ReadValue() + { + return _reader.TokenType switch + { + JsonToken.String => ReadString(), + JsonToken.Integer => ReadInt32(), + JsonToken.Boolean => ReadBoolean(), + + var token => ThrowNotSupported(token) + }; + + [DoesNotReturn] + static object? ThrowNotSupported(JsonToken token) + { + throw new NotSupportedException( + SR.FormatCould_not_read_value_JSON_token_was_0(token)); + } + } + public Uri? ReadUri(string propertyName) { ReadPropertyName(propertyName); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataWriter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataWriter.cs index 028ca319c84..92726dc3aad 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataWriter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/JsonDataWriter.cs @@ -41,6 +41,11 @@ private JsonDataWriter() { } + public void Write(bool value) + { + _writer.WriteValue(value); + } + public void Write(string propertyName, bool value) { _writer.WritePropertyName(propertyName); @@ -63,6 +68,11 @@ public void WriteIfNotFalse(string propertyName, bool value) } } + public void Write(int value) + { + _writer.WriteValue(value); + } + public void Write(string propertyName, int value) { _writer.WritePropertyName(propertyName); @@ -77,6 +87,11 @@ public void WriteIfNotDefault(string propertyName, int value, int defaultValue = } } + public void Write(string? value) + { + _writer.WriteValue(value); + } + public void Write(string propertyName, string? value) { _writer.WritePropertyName(propertyName); @@ -99,6 +114,31 @@ public void WriteIfNotNull(string propertyName, string? value) } } + public void WriteValue(object? value) + { + switch (value) + { + case string s: + Write(s); + break; + + case int i: + Write(i); + break; + + case bool b: + Write(b); + break; + + case null: + Write((string?)null); + break; + + default: + throw new NotSupportedException(); + } + } + public void Write(string propertyName, Uri? value) { _writer.WritePropertyName(propertyName); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeParameterReader.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeParameterReader.cs index b488b916cbd..91798029d05 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeParameterReader.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeParameterReader.cs @@ -34,7 +34,18 @@ private static void ReadIsEnum(JsonDataReader reader, ref BoundAttributeParamete => arg.Builder.IsEnum = reader.ReadBoolean(); private static void ReadDocumentation(JsonDataReader reader, ref BoundAttributeParameterReader arg) - => arg.Builder.Documentation = Cached(reader.ReadString()); + { + var documentationObject = ReadDocumentationObject(reader); + + if (documentationObject is string text) + { + arg.Builder.SetDocumentation(Cached(text)); + } + else + { + arg.Builder.SetDocumentation(documentationObject as DocumentationDescriptor); + } + } private static void ReadMetadata(JsonDataReader reader, ref BoundAttributeParameterReader arg) => reader.ProcessObject(arg.Builder.Metadata, ProcessMetadata); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeReader.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeReader.cs index 8c8ce3b0459..e311ae35763 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeReader.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.BoundAttributeReader.cs @@ -35,7 +35,18 @@ private static void ReadTypeName(JsonDataReader reader, ref BoundAttributeReader => arg.Builder.TypeName = Cached(reader.ReadString()); private static void ReadDocumentation(JsonDataReader reader, ref BoundAttributeReader arg) - => arg.Builder.Documentation = Cached(reader.ReadString()); + { + var documentationObject = ReadDocumentationObject(reader); + + if (documentationObject is string text) + { + arg.Builder.SetDocumentation(Cached(text)); + } + else + { + arg.Builder.SetDocumentation(documentationObject as DocumentationDescriptor); + } + } private static void ReadIndexerNamePrefix(JsonDataReader reader, ref BoundAttributeReader arg) { diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.TagHelperReader.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.TagHelperReader.cs index 88cc0de5260..8bcb7aadd41 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.TagHelperReader.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.TagHelperReader.cs @@ -20,7 +20,18 @@ private record struct TagHelperReader(TagHelperDescriptorBuilder Builder) (nameof(TagHelperDescriptor.Metadata), ReadMetadata)); private static void ReadDocumentation(JsonDataReader reader, ref TagHelperReader arg) - => arg.Builder.Documentation = Cached(reader.ReadString()); + { + var documentationObject = ReadDocumentationObject(reader); + + if (documentationObject is string text) + { + arg.Builder.SetDocumentation(Cached(text)); + } + else + { + arg.Builder.SetDocumentation(documentationObject as DocumentationDescriptor); + } + } private static void ReadTagOutputHint(JsonDataReader reader, ref TagHelperReader arg) => arg.Builder.TagOutputHint = Cached(reader.ReadString()); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.cs index 5099c924eb5..c704a76300e 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectReaders.cs @@ -122,6 +122,27 @@ public static TagHelperDescriptor ReadTagHelperFromProperties(JsonDataReader rea return descriptor; } + private static object? ReadDocumentationObject(JsonDataReader reader) + { + if (reader.IsObjectStart) + { + return reader.ReadNonNullObject(static reader => + { + var id = (DocumentationId)reader.ReadInt32(nameof(DocumentationDescriptor.Id)); + // Check to see if the Args property was actually written before trying to read it; + // otherwise, assume the args are null. + var args = reader.TryReadPropertyName(nameof(DocumentationDescriptor.Args)) + ? reader.ReadArray(static r => r.ReadValue()) + : null; + return DocumentationDescriptor.From(id, args); + }); + } + else + { + return reader.ReadString(); + } + } + private static void ProcessDiagnostic(JsonDataReader reader, RazorDiagnosticCollection collection) { DiagnosticData data = default; diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs index eb5df188c43..91ab97be733 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs @@ -83,7 +83,7 @@ public static void WriteProperties(JsonDataWriter writer, TagHelperDescriptor va writer.Write(nameof(value.Kind), value.Kind); writer.Write(nameof(value.Name), value.Name); writer.Write(nameof(value.AssemblyName), value.AssemblyName); - writer.WriteIfNotNull(nameof(value.Documentation), value.Documentation); + WriteDocumentationObject(writer, nameof(value.Documentation), value.DocumentationObject); writer.WriteIfNotNull(nameof(value.TagOutputHint), value.TagOutputHint); writer.Write(nameof(value.CaseSensitive), value.CaseSensitive); writer.WriteArray(nameof(value.TagMatchingRules), value.TagMatchingRules, WriteTagMatchingRule); @@ -92,6 +92,32 @@ public static void WriteProperties(JsonDataWriter writer, TagHelperDescriptor va writer.WriteArrayIfNotNullOrEmpty(nameof(value.Diagnostics), value.Diagnostics, Write); writer.WriteObject(nameof(value.Metadata), value.Metadata, WriteMetadata); + static void WriteDocumentationObject(JsonDataWriter writer, string propertyName, object? documentationObject) + { + switch (documentationObject) + { + case DocumentationDescriptor descriptor: + writer.WriteObject(propertyName, descriptor, static (writer, value) => + { + writer.Write(nameof(value.Id), (int)value.Id); + if (value.Args is { Length: > 0 }) + { + writer.WriteArray(nameof(value.Args), value.Args, static (w, v) => w.WriteValue(v)); + } + }); + + break; + + case string text: + writer.Write(propertyName, text); + break; + + case null: + // Don't write anything if there isn't any documentation. + break; + } + } + static void WriteTagMatchingRule(JsonDataWriter writer, TagMatchingRuleDescriptor value) { writer.WriteObject(value, static (writer, value) => @@ -132,7 +158,7 @@ static void WriteBoundAttribute(JsonDataWriter writer, BoundAttributeDescriptor writer.WriteIfNotTrue(nameof(value.IsEditorRequired), value.IsEditorRequired); writer.WriteIfNotNull(nameof(value.IndexerNamePrefix), value.IndexerNamePrefix); writer.WriteIfNotNull(nameof(value.IndexerTypeName), value.IndexerTypeName); - writer.WriteIfNotNull(nameof(value.Documentation), value.Documentation); + WriteDocumentationObject(writer, nameof(value.Documentation), value.DocumentationObject); writer.WriteArrayIfNotNullOrEmpty(nameof(value.Diagnostics), value.Diagnostics, Write); writer.WriteObject(nameof(value.Metadata), value.Metadata, WriteMetadata); writer.WriteArrayIfNotNullOrEmpty(nameof(value.BoundAttributeParameters), value.BoundAttributeParameters, WriteBoundAttributeParameter); @@ -146,7 +172,7 @@ static void WriteBoundAttributeParameter(JsonDataWriter writer, BoundAttributePa writer.Write(nameof(value.Name), value.Name); writer.Write(nameof(value.TypeName), value.TypeName); writer.WriteIfNotTrue(nameof(value.IsEnum), value.IsEnum); - writer.WriteIfNotNull(nameof(value.Documentation), value.Documentation); + WriteDocumentationObject(writer, nameof(value.Documentation), value.DocumentationObject); writer.WriteArrayIfNotNullOrEmpty(nameof(value.Diagnostics), value.Diagnostics, Write); writer.WriteObject(nameof(value.Metadata), value.Metadata, WriteMetadata); }); From 08b520241e400276c8dbf8bf6558724bc189efae Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Mon, 15 May 2023 15:58:22 -0700 Subject: [PATCH 04/10] Unify code that switches on documentation object type --- .../src/BoundAttributeDescriptor.cs | 18 ++---- .../src/BoundAttributeDescriptorComparer.cs | 6 +- .../src/BoundAttributeParameterDescriptor.cs | 18 ++---- ...undAttributeParameterDescriptorComparer.cs | 6 +- .../src/ComparerUtilities.cs | 11 ---- .../src/DefaultBoundAttributeDescriptor.cs | 2 +- ...tBoundAttributeDescriptorBuilder.Policy.cs | 2 +- .../DefaultBoundAttributeDescriptorBuilder.cs | 20 ++----- ...efaultBoundAttributeParameterDescriptor.cs | 2 +- ...ributeParameterDescriptorBuilder.Policy.cs | 2 +- ...oundAttributeParameterDescriptorBuilder.cs | 20 ++----- .../src/DefaultTagHelperDescriptor.cs | 2 +- ...efaultTagHelperDescriptorBuilder.Policy.cs | 2 +- .../src/DefaultTagHelperDescriptorBuilder.cs | 22 ++----- .../src/DocumentationObject.cs | 60 +++++++++++++++++++ .../src/Resources.resx | 3 + .../src/TagHelperDescriptor.cs | 18 ++---- .../src/TagHelperDescriptorComparer.cs | 6 +- .../Serialization/ObjectWriters.cs | 4 +- .../Assumed.cs | 29 +++++++++ .../Resources/SR.resx | 3 + .../Resources/xlf/SR.cs.xlf | 5 ++ .../Resources/xlf/SR.de.xlf | 5 ++ .../Resources/xlf/SR.es.xlf | 5 ++ .../Resources/xlf/SR.fr.xlf | 5 ++ .../Resources/xlf/SR.it.xlf | 5 ++ .../Resources/xlf/SR.ja.xlf | 5 ++ .../Resources/xlf/SR.ko.xlf | 5 ++ .../Resources/xlf/SR.pl.xlf | 5 ++ .../Resources/xlf/SR.pt-BR.xlf | 5 ++ .../Resources/xlf/SR.ru.xlf | 5 ++ .../Resources/xlf/SR.tr.xlf | 5 ++ .../Resources/xlf/SR.zh-Hans.xlf | 5 ++ .../Resources/xlf/SR.zh-Hant.xlf | 5 ++ 34 files changed, 199 insertions(+), 122 deletions(-) create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationObject.cs create mode 100644 src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs index 5d408102c09..dfc325f3539 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptor.cs @@ -28,7 +28,7 @@ public abstract class BoundAttributeDescriptor : IEquatable (_flags & flag) != 0; private void SetFlag(int toSet) => ThreadSafeFlagOperations.Set(ref _flags, toSet); @@ -94,21 +94,11 @@ public bool HasIndexer public string Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - protected set => _documentationObject = value; + get => _documentationObject.GetText(); + protected set => _documentationObject = new(value); } - internal object DocumentationObject + internal DocumentationObject DocumentationObject { get => _documentationObject; set => _documentationObject = value; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs index 6eb04f12d3e..a925915f3b0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeDescriptorComparer.cs @@ -44,16 +44,12 @@ public bool Equals(BoundAttributeDescriptor? descriptorX, BoundAttributeDescript descriptorX.IndexerNamePrefix != descriptorY.IndexerNamePrefix || descriptorX.TypeName != descriptorY.TypeName || descriptorX.IndexerTypeName != descriptorY.IndexerTypeName || + descriptorX.DocumentationObject != descriptorY.DocumentationObject || descriptorX.DisplayName != descriptorY.DisplayName) { return false; } - if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) - { - return false; - } - if (!ComparerUtilities.Equals(descriptorX.BoundAttributeParameters, descriptorY.BoundAttributeParameters, BoundAttributeParameterDescriptorComparer.Default)) { return false; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs index c6b0b5c9620..28b3b38fc67 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptor.cs @@ -18,7 +18,7 @@ public abstract class BoundAttributeParameterDescriptor : IEquatable (_flags & flag) != 0; private void SetFlag(int toSet) => ThreadSafeFlagOperations.Set(ref _flags, toSet); @@ -56,21 +56,11 @@ public bool IsBooleanProperty public string Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - protected set => _documentationObject = value; + get => _documentationObject.GetText(); + protected set => _documentationObject = new(value); } - internal object DocumentationObject + internal DocumentationObject DocumentationObject { get => _documentationObject; set => _documentationObject = value; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs index 2a7cbd256c8..5f46d6eb7bc 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/BoundAttributeParameterDescriptorComparer.cs @@ -38,16 +38,12 @@ public bool Equals(BoundAttributeParameterDescriptor? descriptorX, BoundAttribut descriptorX.IsEnum != descriptorY.IsEnum || descriptorX.Name != descriptorY.Name || descriptorX.TypeName != descriptorY.TypeName || + descriptorX.DocumentationObject != descriptorY.DocumentationObject || descriptorX.DisplayName != descriptorY.DisplayName) { return false; } - if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) - { - return false; - } - if (descriptorX.Metadata is MetadataCollection metadataX && descriptorY.Metadata is MetadataCollection metadataY && !metadataX.Equals(metadataY)) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs index d0b081199f8..49462614043 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/ComparerUtilities.cs @@ -9,17 +9,6 @@ namespace Microsoft.AspNetCore.Razor.Language; internal static class ComparerUtilities { - public static bool AreDocumentationObjectsEqual(object? x, object? y) - { - return (x, y) switch - { - (string s1, string s2) => s1 == s2, - (DocumentationDescriptor d1, DocumentationDescriptor d2) => d1.Equals(d2), - (null, null) => true, - _ => false - }; - } - public static bool Equals(IReadOnlyList? first, IReadOnlyList? second, IEqualityComparer? comparer) { if (first == second) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs index 628dd806f89..706aadcbf9f 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptor.cs @@ -13,7 +13,7 @@ public DefaultBoundAttributeDescriptor( bool hasIndexer, string? indexerNamePrefix, string? indexerTypeName, - object? documentationObject, + DocumentationObject documentationObject, string? displayName, bool caseSensitive, bool isEditorRequired, diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs index e637ac0264a..688985167b1 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.Policy.cs @@ -15,7 +15,7 @@ public override bool Return(DefaultBoundAttributeDescriptorBuilder builder) { builder._parent = null; builder._kind = null; - builder._documentationObject = null; + builder._documentationObject = default; builder.Name = null; builder.TypeName = null; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs index c3d98e0ec5c..ad73bd780fa 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultBoundAttributeDescriptorBuilder.cs @@ -55,7 +55,7 @@ private static readonly ObjectPool> s [AllowNull] private string _kind; private List? _attributeParameterBuilders; - private object? _documentationObject; + private DocumentationObject _documentationObject; private Dictionary? _metadata; private RazorDiagnosticCollection? _diagnostics; @@ -78,18 +78,8 @@ public DefaultBoundAttributeDescriptorBuilder(DefaultTagHelperDescriptorBuilder public override string? Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - set => _documentationObject = value; + get => _documentationObject.GetText(); + set => _documentationObject = new(value); } public override string? DisplayName { get; set; } @@ -116,12 +106,12 @@ public override void BindAttributeParameter(Action? _metadata; private RazorDiagnosticCollection? _diagnostics; @@ -51,18 +51,8 @@ public DefaultBoundAttributeParameterDescriptorBuilder(DefaultBoundAttributeDesc public override string? Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - set => _documentationObject = value; + get => _documentationObject.GetText(); + set => _documentationObject = new(value); } public override string? DisplayName { get; set; } @@ -75,12 +65,12 @@ public override string? Documentation internal override void SetDocumentation(string text) { - _documentationObject = text; + _documentationObject = new(text); } internal override void SetDocumentation(DocumentationDescriptor documentation) { - _documentationObject = documentation; + _documentationObject = new(documentation); } public BoundAttributeParameterDescriptor Build() diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs index ea198f53441..96d662841d8 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptor.cs @@ -10,7 +10,7 @@ public DefaultTagHelperDescriptor( string name, string assemblyName, string displayName, - object? documentationObject, + DocumentationObject documentationObject, string? tagOutputHint, bool caseSensitive, TagMatchingRuleDescriptor[] tagMatchingRules, diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs index 0dfc8426d79..0d0ac58c7ac 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.Policy.cs @@ -16,7 +16,7 @@ public override bool Return(DefaultTagHelperDescriptorBuilder builder) builder._kind = null; builder._name = null; builder._assemblyName = null; - builder._documentationObject = null; + builder._documentationObject = default; builder.DisplayName = null; builder.TagOutputHint = null; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs index b4aa296e4eb..c1b41e7f367 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DefaultTagHelperDescriptorBuilder.cs @@ -45,7 +45,7 @@ private static readonly ObjectPool> s_tagMatc private string? _name; private string? _assemblyName; - private object? _documentationObject; + private DocumentationObject _documentationObject; private List? _allowedChildTags; private List? _attributeBuilders; @@ -77,18 +77,8 @@ public DefaultTagHelperDescriptorBuilder(string kind, string name, string assemb public override string? Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - set => _documentationObject = value; + get => _documentationObject.GetText(); + set => _documentationObject = new(value); } public override IDictionary Metadata => _metadata; @@ -168,12 +158,12 @@ public override void TagMatchingRule(Action co internal override void SetDocumentation(string text) { - _documentationObject = text; + _documentationObject = new(text); } internal override void SetDocumentation(DocumentationDescriptor documentation) { - _documentationObject = documentation; + _documentationObject = new(documentation); } public override TagHelperDescriptor Build() @@ -205,7 +195,7 @@ public override TagHelperDescriptor Build() public override void Reset() { - _documentationObject = null; + _documentationObject = default; TagOutputHint = null; _allowedChildTags?.Clear(); _attributeBuilders?.Clear(); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationObject.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationObject.cs new file mode 100644 index 00000000000..c2436283d94 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationObject.cs @@ -0,0 +1,60 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Microsoft.AspNetCore.Razor.Language; + +/// +/// Helper struct that wraps a , , or . +/// +internal readonly record struct DocumentationObject +{ + public readonly object? Object; + + public DocumentationObject(object? obj) + { + if (obj is not (DocumentationDescriptor or string or null)) + { + throw new ArgumentException( + Resources.FormatA_documentation_object_can_only_be_a_0_instance_string_or_null(nameof(DocumentationDescriptor)), + paramName: nameof(obj)); + } + + Object = obj; + } + + public readonly string? GetText() + => Object switch + { + DocumentationDescriptor d => d.GetText(), + string s => s, + null => null, + _ => Assumed.Unreachable() + }; + + public override int GetHashCode() + => Object switch + { + DocumentationDescriptor d => d.GetHashCode(), + string s => s.GetHashCode(), + null => 0, + _ => Assumed.Unreachable() + }; + + public bool Equals(DocumentationObject other) + => (Object, other.Object) switch + { + (DocumentationDescriptor d1, DocumentationDescriptor d2) => d1.Equals(d2), + (string s1, string s2) => s1 == s2, + (null, null) => true, + (DocumentationDescriptor or string or null, DocumentationDescriptor or string or null) => false, + _ => Assumed.Unreachable() + }; + + public static implicit operator DocumentationObject(string text) + => new(text); + + public static implicit operator DocumentationObject(DocumentationDescriptor descriptor) + => new(descriptor); +} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx index fbf2cc2b34d..8ee8fe94bc4 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Resources.resx @@ -586,4 +586,7 @@ Unknown documentation id: '{0}'. + + A documentation object can only be a '{0}' instance, string, or null. + \ No newline at end of file diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs index 78a158b3992..294dc566eb2 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptor.cs @@ -23,7 +23,7 @@ public abstract class TagHelperDescriptor : IEquatable private int _flags; private int? _hashCode; - private object _documentationObject; + private DocumentationObject _documentationObject; private IEnumerable _allDiagnostics; private BoundAttributeDescriptor[] _editorRequiredAttributes; @@ -52,21 +52,11 @@ protected TagHelperDescriptor(string kind) public string Documentation { - get - { - return _documentationObject switch - { - string s => s, - DocumentationDescriptor d => d.GetText(), - null => null, - _ => throw new NotSupportedException() - }; - } - - protected set => _documentationObject = value; + get => _documentationObject.GetText(); + protected set => _documentationObject = new(value); } - internal object DocumentationObject + internal DocumentationObject DocumentationObject { get => _documentationObject; set => _documentationObject = value; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs index 43f5e61648e..b6fa3f3d3cb 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/TagHelperDescriptorComparer.cs @@ -35,16 +35,12 @@ public bool Equals(TagHelperDescriptor? descriptorX, TagHelperDescriptor? descri descriptorX.Name != descriptorY.Name || descriptorX.CaseSensitive != descriptorY.CaseSensitive || descriptorX.DisplayName != descriptorY.DisplayName || + descriptorX.DocumentationObject != descriptorY.DocumentationObject || descriptorX.TagOutputHint != descriptorY.TagOutputHint) { return false; } - if (!ComparerUtilities.AreDocumentationObjectsEqual(descriptorX.DocumentationObject, descriptorY.DocumentationObject)) - { - return false; - } - if (!ComparerUtilities.Equals(descriptorX.BoundAttributes, descriptorY.BoundAttributes, BoundAttributeDescriptorComparer.Default) || !ComparerUtilities.Equals(descriptorX.TagMatchingRules, descriptorY.TagMatchingRules, TagMatchingRuleDescriptorComparer.Default) || !ComparerUtilities.Equals(descriptorX.AllowedChildTags, descriptorY.AllowedChildTags, AllowedChildTagDescriptorComparer.Default) || diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs index 91ab97be733..e7893a3f4b6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs @@ -92,9 +92,9 @@ public static void WriteProperties(JsonDataWriter writer, TagHelperDescriptor va writer.WriteArrayIfNotNullOrEmpty(nameof(value.Diagnostics), value.Diagnostics, Write); writer.WriteObject(nameof(value.Metadata), value.Metadata, WriteMetadata); - static void WriteDocumentationObject(JsonDataWriter writer, string propertyName, object? documentationObject) + static void WriteDocumentationObject(JsonDataWriter writer, string propertyName, DocumentationObject documentationObject) { - switch (documentationObject) + switch (documentationObject.Object) { case DocumentationDescriptor descriptor: writer.WriteObject(propertyName, descriptor, static (writer, value) => diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs new file mode 100644 index 00000000000..1120ecf4c48 --- /dev/null +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT license. See License.txt in the project root for license information. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.AspNetCore.Razor; + +internal static class Assumed +{ + private static readonly Exception s_unreachable + = new InvalidOperationException(SR.This_program_location_is_throught_to_be_unreachable); + + /// + /// Can be called at points that are assumed to be unreachable at runtime. + /// + /// + [DoesNotReturn] + public static void Unreachable() + => throw s_unreachable; + + /// + /// Can be called at points that are assumed to be unreachable at runtime. + /// + /// + [DoesNotReturn] + public static T Unreachable() + => throw s_unreachable; +} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx index 06f0b7520d2..1a8abf8ad28 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx @@ -120,4 +120,7 @@ Non-negative number required. + + This program location is thought to be unreachable. + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf index 99c7d1f466e..1b69347aed0 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf @@ -7,6 +7,11 @@ Vyžaduje se nezáporné číslo. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf index d61a2f23a48..d03e39f904b 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf @@ -7,6 +7,11 @@ Nicht negative Zahl erforderlich. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf index e59560e1a65..5cbf8b5290a 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf @@ -7,6 +7,11 @@ Se requiere un número no negativo. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf index cff37f4e49f..7e2bd31f023 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf @@ -7,6 +7,11 @@ Nombre non négatif obligatoire. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf index 38c32727097..fa517d9e22d 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf @@ -7,6 +7,11 @@ Numero non negativo obbligatorio. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf index 55468a9f6e7..c7bd73f0842 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf @@ -7,6 +7,11 @@ 負でない数値が必要です。 + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf index 2ac38e81bca..d6e36492d6c 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf @@ -7,6 +7,11 @@ 음수가 아닌 수가 필요합니다. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf index 0cea4403618..3101b215af7 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf @@ -7,6 +7,11 @@ Wymagana jest liczba nieujemna. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf index 3c1523d2d22..b498f9226c7 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf @@ -7,6 +7,11 @@ É necessário um número não negativo. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf index 89a1d223993..8da80a1b14c 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf @@ -7,6 +7,11 @@ Требуется неотрицательное число. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf index 0951c22ab1a..e1a596cd795 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf @@ -7,6 +7,11 @@ Negatif olmayan sayı gerekiyor. + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf index cbf51251638..3aa6f8ff477 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf @@ -7,6 +7,11 @@ 需要提供非负数。 + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf index 2b34275672d..a8ad07e74c7 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf @@ -7,6 +7,11 @@ 需要非負數。 + + This program location is thought to be unreachable. + This program location is thought to be unreachable. + + \ No newline at end of file From 297ca307766b9a7bd94ca5d9f9d1ca90f3d4781c Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 08:49:18 -0700 Subject: [PATCH 05/10] Clean up pattern matching in FormattedDescriptor --- .../src/DocumentationDescriptor.FormattedDescriptor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs index 256a5ee71e7..3dfc66831f0 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs @@ -22,7 +22,7 @@ public FormattedDescriptor(DocumentationId id, object?[] args) foreach (var arg in args) { Debug.Assert( - arg is string || arg is int || arg is bool || arg is null, + arg is string or int or bool or null, "Only string, int, bool, or null arguments are allowed."); } #endif @@ -62,7 +62,6 @@ public override bool Equals(DocumentationDescriptor other) (string s1, string s2) => s1 == s2, (int i1, int i2) => i1 == i2, (bool b1, bool b2) => b1 == b2, - (object o1, object o2) => Equals(o1, o2), (null, null) => true, _ => false }; From 9fb93852549fe4e5979adf49549a2fe877b5b5b2 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 09:21:54 -0700 Subject: [PATCH 06/10] Add explanatory comments and remove DocumentationDescriptor.Format(...) --- .../src/DocumentationDescriptor.cs | 14 ++++++++++---- .../src/BindTagHelperDescriptorProvider.cs | 16 ++++++++-------- .../src/ComponentTagHelperDescriptorProvider.cs | 4 ++-- .../EventHandlerTagHelperDescriptorProvider.cs | 8 ++++---- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs index bb7d0403290..6d276623404 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs @@ -28,9 +28,6 @@ internal abstract partial class DocumentationDescriptor : IEquatable new FormattedDescriptor(id, args); - public static DocumentationDescriptor From(DocumentationId id, params object?[]? args) { if (args is null or { Length: 0 }) @@ -58,11 +55,17 @@ public static DocumentationDescriptor From(DocumentationId id, params object?[]? DocumentationId.RefTagHelper => RefTagHelper, DocumentationId.SplatTagHelper => SplatTagHelper, + // If this exception is thrown, there are two potential problems: + // + // 1. Arguments are being passed for a DocumentationId that doesn't require formatting. + // 2. A new DocumentationId was added that needs an entry added in the switch expression above + // to return a DocumentationDescriptor. + _ => throw new NotSupportedException(Resources.FormatUnknown_documentation_id_0(id)) }; } - return Format(id, args); + return new FormattedDescriptor(id, args); } public DocumentationId Id { get; } @@ -112,6 +115,9 @@ private string GetDocumentationText() DocumentationId.RefTagHelper => ComponentResources.RefTagHelper_Documentation, DocumentationId.SplatTagHelper => ComponentResources.SplatTagHelper_Documentation, + // If this exception is thrown, a new DocumentationId was added that needs an entry added in + // the switch expression above to return a resource string. + var id => throw new NotSupportedException(Resources.FormatUnknown_documentation_id_0(id)) }; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs index d6a9e020c9a..67cbe2ea0ac 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/BindTagHelperDescriptorProvider.cs @@ -198,7 +198,7 @@ static TagHelperDescriptor CreateFallbackBindTagHelper() parameter.Name = "event"; parameter.TypeName = typeof(string).FullName; parameter.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Fallback_Event, attributeName)); parameter.SetPropertyName("Event"); @@ -384,7 +384,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I builder.CaseSensitive = true; builder.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Element, entry.ValueAttribute, entry.ChangeAttribute)); @@ -472,7 +472,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I { a.Metadata[ComponentMetadata.Common.DirectiveAttribute] = bool.TrueString; a.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Element, entry.ValueAttribute, entry.ChangeAttribute)); @@ -489,7 +489,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I parameter.Name = "format"; parameter.TypeName = typeof(string).FullName; parameter.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Element_Format, attributeName)); @@ -501,7 +501,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I parameter.Name = "event"; parameter.TypeName = typeof(string).FullName; parameter.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Element_Event, attributeName)); @@ -552,7 +552,7 @@ private static ImmutableArray CreateElementBindTagHelpers(I attribute.Name = formatAttributeName; attribute.TypeName = "System.String"; attribute.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Element_Format, attributeName)); @@ -635,7 +635,7 @@ private static ImmutableArray CreateComponentBindTagHelpers builder.DisplayName = tagHelper.DisplayName; builder.CaseSensitive = true; builder.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Component, valueAttribute.Name, changeAttribute.Name)); @@ -689,7 +689,7 @@ private static ImmutableArray CreateComponentBindTagHelpers { attribute.Metadata[ComponentMetadata.Common.DirectiveAttribute] = bool.TrueString; attribute.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.BindTagHelper_Component, valueAttribute.Name, changeAttribute.Name)); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs index 68052369df0..61f7e5984f1 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs @@ -441,7 +441,7 @@ private static void CreateTypeParameterProperty(TagHelperDescriptorBuilder build } pb.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.ComponentTypeParameter, typeParameter.Name, builder.Name)); @@ -544,7 +544,7 @@ private static void CreateContextParameter(TagHelperDescriptorBuilder builder, s var documentation = childContentName == null ? DocumentationDescriptor.ChildContentParameterName_TopLevel - : DocumentationDescriptor.Format(DocumentationId.ChildContentParameterName, childContentName); + : DocumentationDescriptor.From(DocumentationId.ChildContentParameterName, childContentName); b.SetDocumentation(documentation); }); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs index 49639149cc9..7852cf071e0 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/src/EventHandlerTagHelperDescriptorProvider.cs @@ -145,7 +145,7 @@ private static ImmutableArray CreateEventHandlerTagHelpers( builder.CaseSensitive = true; builder.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.EventHandlerTagHelper, attributeName, eventArgType)); @@ -206,7 +206,7 @@ private static ImmutableArray CreateEventHandlerTagHelpers( builder.BindAttribute(a => { a.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.EventHandlerTagHelper, attributeName, eventArgType)); @@ -233,7 +233,7 @@ private static ImmutableArray CreateEventHandlerTagHelpers( parameter.Name = "preventDefault"; parameter.TypeName = typeof(bool).FullName; parameter.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.EventHandlerTagHelper_PreventDefault, attributeName)); @@ -248,7 +248,7 @@ private static ImmutableArray CreateEventHandlerTagHelpers( parameter.Name = "stopPropagation"; parameter.TypeName = typeof(bool).FullName; parameter.SetDocumentation( - DocumentationDescriptor.Format( + DocumentationDescriptor.From( DocumentationId.EventHandlerTagHelper_StopPropagation, attributeName)); From 5aae02d81f4e65a03dc9f32e3a292313418f8b77 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 09:25:27 -0700 Subject: [PATCH 07/10] Add Debug.Fail(...) to catch future problems --- .../Serialization/ObjectWriters.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs index e7893a3f4b6..70fde19b012 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Serialization/ObjectWriters.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis.Razor.ProjectSystem; @@ -113,7 +114,11 @@ static void WriteDocumentationObject(JsonDataWriter writer, string propertyName, break; case null: - // Don't write anything if there isn't any documentation. + // Don't write a property if there isn't any documentation. + break; + + default: + Debug.Fail($"Documentation objects should only be of type {nameof(DocumentationDescriptor)}, string, or null."); break; } } From 4d8751c4222b1bfc70c2bcd516b092fe0c61f63a Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 09:35:10 -0700 Subject: [PATCH 08/10] Validate 'id' parameter of DocumentationDescriptor.From(...) --- .../src/DocumentationDescriptor.cs | 6 ++++++ .../src/DocumentationId.cs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs index 6d276623404..c01f268c3e5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.cs @@ -30,6 +30,12 @@ internal abstract partial class DocumentationDescriptor : IEquatable DocumentationId.Last) + { + throw new ArgumentOutOfRangeException( + nameof(id), id, Resources.FormatUnknown_documentation_id_0(id)); + } + if (args is null or { Length: 0 }) { return id switch diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs index fceb2e1f32f..8ba520ad2ae 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationId.cs @@ -5,6 +5,9 @@ namespace Microsoft.AspNetCore.Razor.Language; internal enum DocumentationId { + // New values must always be placed at the end of the enum + // and Last must be updated to point to the final value. + // Do NOT insert items or change the order below. BindTagHelper_Fallback, BindTagHelper_Fallback_Event, BindTagHelper_Fallback_Format, @@ -25,4 +28,6 @@ internal enum DocumentationId KeyTagHelper, RefTagHelper, SplatTagHelper, + + Last = SplatTagHelper } From 64bd02d2a42f0d68934024d82ee2c00e5658cb43 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 09:47:00 -0700 Subject: [PATCH 09/10] Simplify SimpleDescriptor.ComputeHashCode() --- .../src/DocumentationDescriptor.FormattedDescriptor.cs | 2 +- .../src/DocumentationDescriptor.SimpleDescriptor.cs | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs index 3dfc66831f0..88ba026fb7c 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.FormattedDescriptor.cs @@ -79,7 +79,7 @@ protected override int ComputeHashCode() { var result = HashCodeCombiner.Start(); - result.Add((int)Id); + result.Add(Id); foreach (var arg in Args) { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs index b15ed62ef01..1cc2112481f 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/DocumentationDescriptor.SimpleDescriptor.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Razor.Language; @@ -24,12 +23,6 @@ public override bool Equals(DocumentationDescriptor other) => other is SimpleDescriptor { Id: var id } && Id == id; protected override int ComputeHashCode() - { - var result = HashCodeCombiner.Start(); - - result.Add((int)Id); - - return result.CombinedHash; - } + => Id.GetHashCode(); } } From 95ab8ad0bb710bff10d64dee9885782a8da168f1 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2023 11:09:55 -0700 Subject: [PATCH 10/10] Update Assumed.Unreachable() to include file/line info --- .../Assumed.cs | 14 +++++++------- .../Resources/SR.resx | 4 ++-- .../Resources/xlf/SR.cs.xlf | 6 +++--- .../Resources/xlf/SR.de.xlf | 6 +++--- .../Resources/xlf/SR.es.xlf | 6 +++--- .../Resources/xlf/SR.fr.xlf | 6 +++--- .../Resources/xlf/SR.it.xlf | 6 +++--- .../Resources/xlf/SR.ja.xlf | 6 +++--- .../Resources/xlf/SR.ko.xlf | 6 +++--- .../Resources/xlf/SR.pl.xlf | 6 +++--- .../Resources/xlf/SR.pt-BR.xlf | 6 +++--- .../Resources/xlf/SR.ru.xlf | 6 +++--- .../Resources/xlf/SR.tr.xlf | 6 +++--- .../Resources/xlf/SR.zh-Hans.xlf | 6 +++--- .../Resources/xlf/SR.zh-Hant.xlf | 6 +++--- 15 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs index 1120ecf4c48..64289e36f98 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Assumed.cs @@ -3,27 +3,27 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; namespace Microsoft.AspNetCore.Razor; internal static class Assumed { - private static readonly Exception s_unreachable - = new InvalidOperationException(SR.This_program_location_is_throught_to_be_unreachable); - /// /// Can be called at points that are assumed to be unreachable at runtime. /// /// [DoesNotReturn] - public static void Unreachable() - => throw s_unreachable; + public static void Unreachable([CallerFilePath] string? path = null, [CallerLineNumber] int line = 0) + => throw new InvalidOperationException( + SR.FormatThis_program_location_is_throught_to_be_unreachable_File_0_Line_1(path, line)); /// /// Can be called at points that are assumed to be unreachable at runtime. /// /// [DoesNotReturn] - public static T Unreachable() - => throw s_unreachable; + public static T Unreachable([CallerFilePath] string? path = null, [CallerLineNumber] int line = 0) + => throw new InvalidOperationException( + SR.FormatThis_program_location_is_throught_to_be_unreachable_File_0_Line_1(path, line)); } diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx index 1a8abf8ad28..9a4ffd1b530 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/SR.resx @@ -120,7 +120,7 @@ Non-negative number required. - - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} \ No newline at end of file diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf index 1b69347aed0..e2c01d926a9 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.cs.xlf @@ -7,9 +7,9 @@ Vyžaduje se nezáporné číslo. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf index d03e39f904b..071952737be 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.de.xlf @@ -7,9 +7,9 @@ Nicht negative Zahl erforderlich. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf index 5cbf8b5290a..5a6d70fb78a 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.es.xlf @@ -7,9 +7,9 @@ Se requiere un número no negativo. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf index 7e2bd31f023..1ebf08ac092 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.fr.xlf @@ -7,9 +7,9 @@ Nombre non négatif obligatoire. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf index fa517d9e22d..bda9f77bf9a 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.it.xlf @@ -7,9 +7,9 @@ Numero non negativo obbligatorio. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf index c7bd73f0842..27fea5792b7 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ja.xlf @@ -7,9 +7,9 @@ 負でない数値が必要です。 - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf index d6e36492d6c..a2af6807855 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ko.xlf @@ -7,9 +7,9 @@ 음수가 아닌 수가 필요합니다. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf index 3101b215af7..18490cbc678 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pl.xlf @@ -7,9 +7,9 @@ Wymagana jest liczba nieujemna. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf index b498f9226c7..a41760514c8 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.pt-BR.xlf @@ -7,9 +7,9 @@ É necessário um número não negativo. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf index 8da80a1b14c..37f9d6188a5 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.ru.xlf @@ -7,9 +7,9 @@ Требуется неотрицательное число. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf index e1a596cd795..d57e895053b 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.tr.xlf @@ -7,9 +7,9 @@ Negatif olmayan sayı gerekiyor. - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf index 3aa6f8ff477..e0814e6a5d1 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hans.xlf @@ -7,9 +7,9 @@ 需要提供非负数。 - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1} diff --git a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf index a8ad07e74c7..f932006cf80 100644 --- a/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf +++ b/src/Shared/Microsoft.AspNetCore.Razor.Utilities.Shared/Resources/xlf/SR.zh-Hant.xlf @@ -7,9 +7,9 @@ 需要非負數。 - - This program location is thought to be unreachable. - This program location is thought to be unreachable. + + This program location is thought to be unreachable. File='{0}', Line={1} + This program location is thought to be unreachable. File='{0}', Line={1}