From 1fdc5132cbe06bc74a4ec1fc1471b3de63269ed6 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Thu, 16 Mar 2017 19:24:54 -0700 Subject: [PATCH] React to TagHelper descriptors api cleanup --- .../ModelExpressionPass.cs | 6 +- ...ComponentTagHelperDescriptorConventions.cs | 4 +- .../ViewComponentTagHelperPass.cs | 36 ++--- .../ModelExpressionPassTest.cs | 69 ++++----- ...onentTagHelperDescriptorConventionsTest.cs | 20 +-- .../ViewComponentTagHelperPassTest.cs | 134 ++++++------------ 6 files changed, 106 insertions(+), 163 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs index 7a5962268f..9de73fbb4a 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ModelExpressionPass.cs @@ -10,6 +10,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host { public class ModelExpressionPass : RazorIRPassBase, IRazorIROptimizationPass { + private const string ModelExpressionTypeName = "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression"; + public override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIRNode irDocument) { var visitor = new Visitor(); @@ -22,7 +24,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node) { - if (string.Equals(node.Descriptor.TypeName, "Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression", StringComparison.Ordinal)) + if (string.Equals(node.Descriptor.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) || + (node.IsIndexerNameMatch && + string.Equals(node.Descriptor.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal))) { var expression = new CSharpExpressionIRNode(); var builder = RazorIRBuilder.Create(expression); diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs index 5e7c24ccf7..c35195bf59 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperDescriptorConventions.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host public static class ViewComponentTagHelperDescriptorConventions { /// - /// The key in a containing + /// The key in a containing /// the short name of a view component. /// public static readonly string ViewComponentNameKey = "ViewComponentName"; @@ -22,6 +22,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host /// The to check. /// Whether a represents a view component. public static bool IsViewComponentDescriptor(TagHelperDescriptor descriptor) => - descriptor != null && descriptor.PropertyBag.ContainsKey(ViewComponentNameKey); + descriptor != null && descriptor.Metadata.ContainsKey(ViewComponentNameKey); } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs index da7107c281..1f7ec7080a 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/ViewComponentTagHelperPass.cs @@ -1,8 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.Evolution; @@ -28,7 +28,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host { GenerateVCTHClass(visitor.Class, tagHelper.Value); - if (visitor.Fields.UsedTagHelperTypeNames.Remove(tagHelper.Value.TypeName)) + var tagHelperTypeName = tagHelper.Value.Metadata[ITagHelperDescriptorBuilder.TypeNameKey]; + if (visitor.Fields.UsedTagHelperTypeNames.Remove(tagHelperTypeName)) { visitor.Fields.UsedTagHelperTypeNames.Add(GetVCTHFullName(visitor.Namespace, visitor.Class, tagHelper.Value)); } @@ -77,14 +78,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host ClassDeclarationIRNode @class, TagHelperDescriptor tagHelper) { - var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; + var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; return $"{@namespace.Content}.{@class.Name}.__Generated__{vcName}ViewComponentTagHelper"; } private static string GetVCTHClassName( TagHelperDescriptor tagHelper) { - var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; + var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; return $"__Generated__{vcName}ViewComponentTagHelper"; } @@ -143,18 +144,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host $"global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext", "ViewContext"); - var indexerAttributes = descriptor.Attributes.Where(a => a.IsIndexer); - - foreach (var attribute in descriptor.Attributes) + foreach (var attribute in descriptor.BoundAttributes) { - if (attribute.IsIndexer) - { - continue; - } + writer.WriteAutoPropertyDeclaration( + "public", attribute.TypeName, attribute.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]); - writer.WriteAutoPropertyDeclaration("public", attribute.TypeName, attribute.PropertyName); - - if (indexerAttributes.Any(a => string.Equals(a.PropertyName, attribute.PropertyName, StringComparison.Ordinal))) + if (attribute.IndexerTypeName != null) { writer.Write(" = ") .WriteStartNewObject(attribute.TypeName) @@ -199,11 +194,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host private string[] GetMethodParameters(TagHelperDescriptor descriptor) { - var propertyNames = descriptor.Attributes.Where(a => !a.IsIndexer).Select(attribute => attribute.PropertyName); + var propertyNames = descriptor.BoundAttributes.Select( + attribute => attribute.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]); var joinedPropertyNames = string.Join(", ", propertyNames); var parametersString = $"new {{ { joinedPropertyNames } }}"; - var viewComponentName = descriptor.PropertyBag[ + var viewComponentName = descriptor.Metadata[ ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString }; return methodParameters; @@ -211,9 +207,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host private void BuildTargetElementString(CSharpCodeWriter writer, TagHelperDescriptor descriptor) { + Debug.Assert(descriptor.TagMatchingRules.Count() == 1); + + var rule = descriptor.TagMatchingRules.First(); + writer.Write("[") .WriteStartMethodInvocation("Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute") - .WriteStringLiteral(descriptor.FullTagName) + .WriteStringLiteral(rule.TagName) .WriteLine(")]"); } @@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host if (ViewComponentTagHelperDescriptorConventions.IsViewComponentDescriptor(tagHelper)) { // Capture all the VCTagHelpers (unique by type name) so we can generate a class for each one. - var vcName = tagHelper.PropertyBag[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; + var vcName = tagHelper.Metadata[ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey]; TagHelpers[vcName] = tagHelper; CreateTagHelpers.Add(node); diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs index daaf6d0b5a..3998336a34 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ModelExpressionPassTest.cs @@ -25,21 +25,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "p", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Int32", - Name = "Foo", - } - - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRule(rule => + rule.RequireTagName("p")) + .Build() }; var engine = CreateEngine(tagHelpers); @@ -72,21 +65,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "p", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = typeof(ModelExpression).FullName, - Name = "Foo", - } - - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName(typeof(ModelExpression).FullName)) + .TagMatchingRule(rule => + rule.RequireTagName("p")) + .Build() }; var engine = CreateEngine(tagHelpers); @@ -124,21 +110,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "p", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = typeof(ModelExpression).FullName, - Name = "Foo", - } - - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName(typeof(ModelExpression).FullName)) + .TagMatchingRule(rule => + rule.RequireTagName("p")) + .Build() }; var engine = CreateEngine(tagHelpers); diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs index 9eb24f8437..bcfbfee65c 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperDescriptorConventionsTest.cs @@ -38,22 +38,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host.Test private static TagHelperDescriptor CreateTagHelperDescriptor() { - var descriptor = new TagHelperDescriptor - { - TagName = "tag-name", - TypeName = "TypeName", - AssemblyName = "AssemblyName", - }; + var descriptor = ITagHelperDescriptorBuilder.Create("TypeName", "AssemblyName") + .TagMatchingRule(rule => + rule.RequireTagName("tag-name")) + .Build(); + return descriptor; } private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor() { - var descriptor = CreateTagHelperDescriptor(); - descriptor.PropertyBag.Add( - ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, - "ViewComponentName"); + var descriptor = ITagHelperDescriptorBuilder.Create("TypeName", "AssemblyName") + .TagMatchingRule(rule => + rule.RequireTagName("tag-name")) + .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "ViewComponentName") + .Build(); return descriptor; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs index e71a1554f9..5b34d47e7e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Host.Test/ViewComponentTagHelperPassTest.cs @@ -23,20 +23,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "p", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Int32", - Name = "Foo", - } - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRule(rule => + rule.RequireTagName("p")) + .Build() }; var engine = CreateEngine(tagHelpers); @@ -69,25 +63,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Host var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "tagcloud", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Int32", - Name = "Foo", - PropertyName = "Foo", - } - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRule(rule => + rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud") + .Build() }; - tagHelpers[0].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud"); - var engine = CreateEngine(tagHelpers); var pass = new ViewComponentTagHelperPass() { @@ -146,33 +133,19 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore. var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "tagcloud", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Collections.Generic.Dictionary", - Name = "foo", - PropertyName = "Tags", - IsIndexer = false, - }, - new TagHelperAttributeDescriptor() - { - TypeName = "System.Collections.Generic.Dictionary", - Name = "foo-", - PropertyName = "Tags", - IsIndexer = true, - } - } - } + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Collections.Generic.Dictionary") + .PropertyName("Tags") + .AsDictionary("foo-", "System.Int32")) + .TagMatchingRule(rule => + rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud") + .Build() }; - tagHelpers[0].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud"); - var engine = CreateEngine(tagHelpers); var pass = new ViewComponentTagHelperPass() { @@ -231,39 +204,26 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore. var tagHelpers = new[] { - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "PTestTagHelper", - TagName = "p", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Int32", - Name = "Foo", - } - } - }, - new TagHelperDescriptor() - { - AssemblyName = "TestAssembly", - TypeName = "TestTagHelper", - TagName = "tagcloud", - Attributes = new TagHelperAttributeDescriptor[] - { - new TagHelperAttributeDescriptor() - { - TypeName = "System.Int32", - Name = "Foo", - PropertyName = "Foo", - } - } - } + ITagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32")) + .TagMatchingRule(rule => + rule.RequireTagName("p")) + .Build(), + ITagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") + .BindAttribute(attribute => + attribute + .Name("Foo") + .TypeName("System.Int32") + .PropertyName("Foo")) + .TagMatchingRule(rule => + rule.RequireTagName("tagcloud")) + .AddMetadata(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud") + .Build() }; - tagHelpers[1].PropertyBag.Add(ViewComponentTagHelperDescriptorConventions.ViewComponentNameKey, "TagCloud"); - var engine = CreateEngine(tagHelpers); var pass = new ViewComponentTagHelperPass() {