Make ViewComponentTagHelper's bound attribute display names nicer.

- Went from `typeName __Generated__SomeViewComponentTagHelper.PropertyName` to `typeName SomeViewComponentTagHelper.PropertyName`.
- Updated `TagHelperBoundDescriptorBuilder` to allow setting of `DisplayName`.
- Added `TagHelperBoundAttributeDescriptorBuilderTest` class to verify new `DisplayName` additions.
- Updated `ViewComponentTagHelperDescriptorFactoryTest` expectations.

#1251
This commit is contained in:
N. Taylor Mullen 2017-05-23 15:41:03 -07:00
parent cdddaefa81
commit d917311883
5 changed files with 108 additions and 18 deletions

View File

@ -31,6 +31,7 @@ namespace Microsoft.AspNetCore.Razor.Language
[typeof(decimal).FullName] = "decimal",
};
private string _displayName;
private bool _isEnum;
private bool _hasIndexer;
private string _indexerValueTypeName;
@ -113,6 +114,18 @@ namespace Microsoft.AspNetCore.Razor.Language
return this;
}
public BoundAttributeDescriptorBuilder DisplayName(string displayName)
{
if (displayName == null)
{
throw new ArgumentNullException(nameof(displayName));
}
_displayName = displayName;
return this;
}
public BoundAttributeDescriptor Build()
{
var validationDiagnostics = Validate();
@ -122,12 +135,17 @@ namespace Microsoft.AspNetCore.Razor.Language
diagnostics.UnionWith(_diagnostics);
}
if (!PrimitiveDisplayTypeNameLookups.TryGetValue(_typeName, out var simpleName))
var displayName = _displayName;
if (displayName == null)
{
simpleName = _typeName;
if (!PrimitiveDisplayTypeNameLookups.TryGetValue(_typeName, out var simpleName))
{
simpleName = _typeName;
}
displayName = $"{simpleName} {_containingTypeName}.{_propertyName}";
}
var displayName = $"{simpleName} {_containingTypeName}.{_propertyName}";
var descriptor = new ITagHelperBoundAttributeDescriptor(
_isEnum,
_name,

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
@ -20,6 +21,25 @@ namespace Microsoft.CodeAnalysis.Razor
.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted)
.WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
private static readonly IReadOnlyDictionary<string, string> PrimitiveDisplayTypeNameLookups = new Dictionary<string, string>(StringComparer.Ordinal)
{
[typeof(byte).FullName] = "byte",
[typeof(sbyte).FullName] = "sbyte",
[typeof(int).FullName] = "int",
[typeof(uint).FullName] = "uint",
[typeof(short).FullName] = "short",
[typeof(ushort).FullName] = "ushort",
[typeof(long).FullName] = "long",
[typeof(ulong).FullName] = "ulong",
[typeof(float).FullName] = "float",
[typeof(double).FullName] = "double",
[typeof(char).FullName] = "char",
[typeof(bool).FullName] = "bool",
[typeof(object).FullName] = "object",
[typeof(string).FullName] = "string",
[typeof(decimal).FullName] = "decimal",
};
public ViewComponentTagHelperDescriptorFactory(Compilation compilation)
{
_viewComponentAttributeSymbol = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute);
@ -47,7 +67,7 @@ namespace Microsoft.CodeAnalysis.Razor
AddRequiredAttributes(methodParameters, ruleBuilder);
});
AddBoundAttributes(methodParameters, descriptorBuilder);
AddBoundAttributes(methodParameters, displayName, descriptorBuilder);
}
else
{
@ -148,18 +168,25 @@ namespace Microsoft.CodeAnalysis.Razor
}
}
private void AddBoundAttributes(ImmutableArray<IParameterSymbol> methodParameters, TagHelperDescriptorBuilder builder)
private void AddBoundAttributes(ImmutableArray<IParameterSymbol> methodParameters, string containingDisplayName, TagHelperDescriptorBuilder builder)
{
foreach (var parameter in methodParameters)
{
var lowerKebabName = HtmlConventions.ToHtmlCase(parameter.Name);
var typeName = parameter.Type.ToDisplayString(FullNameTypeDisplayFormat);
if (!PrimitiveDisplayTypeNameLookups.TryGetValue(typeName, out var simpleName))
{
simpleName = typeName;
}
builder.BindAttribute(attributeBuilder =>
{
attributeBuilder
.Name(lowerKebabName)
.PropertyName(parameter.Name)
.TypeName(typeName);
.TypeName(typeName)
.DisplayName($"{simpleName} {containingDisplayName}.{parameter.Name}");
if (parameter.Type.TypeKind == TypeKind.Enum)
{

View File

@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language
{
public class BoundAttributeDescriptorBuilderTest
{
[Fact]
public void DisplayName_SetsDescriptorsDisplayName()
{
// Arrange
var expectedDisplayName = "ExpectedDisplayName";
var builder = BoundAttributeDescriptorBuilder.Create("TestTagHelper");
// Act
var descriptor = builder.DisplayName(expectedDisplayName).Build();
// Assert
Assert.Equal(expectedDisplayName, descriptor.DisplayName);
}
[Fact]
public void DisplayName_DefaultsToPropertyLookingDisplayName()
{
// Arrange
var builder = BoundAttributeDescriptorBuilder.Create("TestTagHelper")
.TypeName(typeof(int).FullName)
.PropertyName("SomeProperty");
// Act
var descriptor = builder.Build();
// Assert
Assert.Equal("int TestTagHelper.SomeProperty", descriptor.DisplayName);
}
}
}

View File

@ -31,12 +31,14 @@ namespace Microsoft.CodeAnalysis.Razor.Workspaces
attribute
.Name("foo")
.PropertyName("foo")
.TypeName(typeof(string).FullName))
.TypeName(typeof(string).FullName)
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
.BindAttribute(attribute =>
attribute
.Name("bar")
.PropertyName("bar")
.TypeName(typeof(string).FullName))
.TypeName(typeof(string).FullName)
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
.AddMetadata(ViewComponentTypes.ViewComponentNameKey, "StringParameter")
.Build();
@ -69,17 +71,20 @@ namespace Microsoft.CodeAnalysis.Razor.Workspaces
.Name("test-enum")
.PropertyName("testEnum")
.TypeName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum))
.AsEnum())
.AsEnum()
.DisplayName(typeof(VariousParameterViewComponent).FullName + "." + nameof(VariousParameterViewComponent.TestEnum) + " VariousParameterViewComponentTagHelper.testEnum"))
.BindAttribute(attribute =>
attribute
.Name("test-string")
.PropertyName("testString")
.TypeName(typeof(string).FullName))
.TypeName(typeof(string).FullName)
.DisplayName("string VariousParameterViewComponentTagHelper.testString"))
.BindAttribute(attribute =>
attribute
.Name("baz")
.PropertyName("baz")
.TypeName(typeof(int).FullName))
.TypeName(typeof(int).FullName)
.DisplayName("int VariousParameterViewComponentTagHelper.baz"))
.AddMetadata(ViewComponentTypes.ViewComponentNameKey, "VariousParameter")
.Build();
@ -109,13 +114,15 @@ namespace Microsoft.CodeAnalysis.Razor.Workspaces
attribute
.Name("foo")
.PropertyName("Foo")
.TypeName("System.Collections.Generic.List<System.String>"))
.TypeName("System.Collections.Generic.List<System.String>")
.DisplayName("System.Collections.Generic.List<System.String> GenericParameterViewComponentTagHelper.Foo"))
.BindAttribute(attribute =>
attribute
.Name("bar")
.PropertyName("Bar")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionary("bar-", typeof(int).FullName))
.AsDictionary("bar-", typeof(int).FullName)
.DisplayName("System.Collections.Generic.Dictionary<System.String, System.Int32> GenericParameterViewComponentTagHelper.Bar"))
.AddMetadata(ViewComponentTypes.ViewComponentNameKey, "GenericParameter")
.Build();

View File

@ -1,10 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
using Xunit;
@ -49,12 +46,14 @@ namespace Microsoft.CodeAnalysis.Razor
attribute
.Name("foo")
.PropertyName("foo")
.TypeName(typeof(string).FullName))
.TypeName(typeof(string).FullName)
.DisplayName("string StringParameterViewComponentTagHelper.foo"))
.BindAttribute(attribute =>
attribute
.Name("bar")
.PropertyName("bar")
.TypeName(typeof(string).FullName))
.TypeName(typeof(string).FullName)
.DisplayName("string StringParameterViewComponentTagHelper.bar"))
.AddMetadata(ViewComponentTypes.ViewComponentNameKey, "StringParameter")
.Build();