Redesign tag helper codegen

This commit is contained in:
Ryan Nowak 2017-06-20 22:38:13 -07:00
parent 2a6f0e4dc9
commit 7aeb228063
218 changed files with 4726 additions and 3637 deletions

View File

@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
@ -103,17 +104,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
Items.Add(new InstrumentationItem(node, Parent, isLiteral: false, source: node.Source.Value));
}
VisitDefault(node);
}
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIntermediateNode node)
{
// We don't want to instrument TagHelper attributes. Do nothing.
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIntermediateNode node)
{
// We don't want to instrument TagHelper attributes. Do nothing.
// Inside a tag helper we only want to visit inside of the body (skip all of the attributes and properties).
for (var i = 0; i < node.Children.Count; i++)
{
var child = node.Children[i];
if (child is TagHelperBodyIntermediateNode ||
child is DefaultTagHelperBodyIntermediateNode)
{
VisitDefault(child);
}
}
}
}
}

View File

@ -23,11 +23,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
public List<TagHelperIntermediateNode> TagHelpers { get; } = new List<TagHelperIntermediateNode>();
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIntermediateNode node)
public override void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node)
{
if (string.Equals(node.Descriptor.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) ||
if (string.Equals(node.BoundAttribute.TypeName, ModelExpressionTypeName, StringComparison.Ordinal) ||
(node.IsIndexerNameMatch &&
string.Equals(node.Descriptor.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal)))
string.Equals(node.BoundAttribute.IndexerTypeName, ModelExpressionTypeName, StringComparison.Ordinal)))
{
var expression = new CSharpExpressionIntermediateNode();

View File

@ -1,106 +1,168 @@
// 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.Language;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
{
public class ViewComponentTagHelperPass : IntermediateNodePassBase, IRazorOptimizationPass
{
// Run after the default taghelper pass
public override int Order => IntermediateNodePassBase.DefaultFeatureOrder + 2000;
private static readonly string[] PublicModifiers = new[] { "public" };
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var visitor = new Visitor();
visitor.Visit(documentNode);
if (visitor.Class == null || visitor.TagHelpers.Count == 0)
var @namespace = documentNode.FindPrimaryNamespace();
var @class = documentNode.FindPrimaryClass();
if (@namespace == null || @class == null)
{
// Nothing to do, bail.
// Nothing to do, bail. We can't function without the standard structure.
return;
}
foreach (var tagHelper in visitor.TagHelpers)
{
GenerateVCTHClass(visitor.Class, tagHelper.Value);
var context = new Context(@namespace, @class);
var tagHelperTypeName = tagHelper.Value.GetTypeName();
if (visitor.Fields.UsedTagHelperTypeNames.Remove(tagHelperTypeName))
// For each VCTH *usage* we need to rewrite the tag helper node to use the tag helper runtime to construct
// and set properties on the the correct field, and using the name of the type we will generate.
var nodes = documentNode.FindDescendantNodes<TagHelperIntermediateNode>();
for (var i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
foreach (var tagHelper in node.TagHelpers)
{
visitor.Fields.UsedTagHelperTypeNames.Add(GetVCTHFullName(visitor.Namespace, visitor.Class, tagHelper.Value));
RewriteUsage(context, node, tagHelper);
}
}
foreach (var (parent, node) in visitor.CreateTagHelpers)
// Then for each VCTH *definition* that we've seen we need to generate the class that implements
// ITagHelper and the field that will hold it.
foreach (var tagHelper in context.TagHelpers)
{
RewriteCreateNode(visitor.Namespace, visitor.Class, (CreateTagHelperIntermediateNode)node, parent);
AddField(context, tagHelper);
AddTagHelperClass(context, tagHelper);
}
}
private void GenerateVCTHClass(ClassDeclarationIntermediateNode @class, TagHelperDescriptor tagHelper)
private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
{
if (!tagHelper.IsViewComponentKind())
{
return;
}
context.Add(tagHelper);
// Now we need to insert a create node using the default tag helper runtime. This is similar to
// code in DefaultTagHelperOptimizationPass.
//
// Find the body node.
var i = 0;
while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode)
{
i++;
}
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode)
{
i++;
}
// Now find the last create node.
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode)
{
i++;
}
// Now i has the right insertion point.
node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode()
{
Field = context.GetFieldName(tagHelper),
TagHelper = tagHelper,
Type = context.GetFullyQualifiedName(tagHelper),
});
// Now we need to rewrite any set property nodes to use the default runtime.
for (i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
propertyNode.TagHelper == tagHelper)
{
// This is a set property for this VCTH - we need to replace it with a node
// that will use our field and property name.
node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode)
{
Field = context.GetFieldName(tagHelper),
Property = propertyNode.BoundAttribute.GetPropertyName(),
};
}
}
}
private void AddField(Context context, TagHelperDescriptor tagHelper)
{
// We need to insert a node for the field that will hold the tag helper. We've already generated a field name
// at this time and use it for all uses of the same tag helper type.
//
// We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing
// field nodes.
var i = 0;
while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode)
{
i++;
}
while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode)
{
i++;
}
context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode()
{
Annotations =
{
{ CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString },
},
Modifiers =
{
"private",
},
Name = context.GetFieldName(tagHelper),
Type = "global::" + context.GetFullyQualifiedName(tagHelper),
});
}
private void AddTagHelperClass(Context context, TagHelperDescriptor tagHelper)
{
var writer = new CodeWriter();
WriteClass(writer, tagHelper);
WriteClass(context, writer, tagHelper);
var statement = new CSharpCodeIntermediateNode();
statement.Children.Add(new IntermediateToken()
var code = new CSharpCodeIntermediateNode();
code.Children.Add(new IntermediateToken()
{
Kind = IntermediateToken.TokenKind.CSharp,
Content = writer.GenerateCode()
});
@class.Children.Add(statement);
context.Class.Children.Add(code);
}
private void RewriteCreateNode(
NamespaceDeclarationIntermediateNode @namespace,
ClassDeclarationIntermediateNode @class,
CreateTagHelperIntermediateNode node,
IntermediateNode parent)
{
var newTypeName = GetVCTHFullName(@namespace, @class, node.Descriptor);
for (var i = 0; i < parent.Children.Count; i++)
{
if (parent.Children[i] is SetTagHelperPropertyIntermediateNode setProperty &&
node.Descriptor.BoundAttributes.Contains(setProperty.Descriptor))
{
setProperty.TagHelperTypeName = newTypeName;
}
}
node.TagHelperTypeName = newTypeName;
}
private static string GetVCTHFullName(
NamespaceDeclarationIntermediateNode @namespace,
ClassDeclarationIntermediateNode @class,
TagHelperDescriptor tagHelper)
{
var vcName = tagHelper.GetViewComponentName();
return $"{@namespace.Content}.{@class.Name}.__Generated__{vcName}ViewComponentTagHelper";
}
private static string GetVCTHClassName(
TagHelperDescriptor tagHelper)
{
var vcName = tagHelper.GetViewComponentName();
return $"__Generated__{vcName}ViewComponentTagHelper";
}
private void WriteClass(CodeWriter writer, TagHelperDescriptor descriptor)
private void WriteClass(Context context, CodeWriter writer, TagHelperDescriptor tagHelper)
{
// Add target element.
BuildTargetElementString(writer, descriptor);
BuildTargetElementString(writer, tagHelper);
// Initialize declaration.
var tagHelperTypeName = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelper";
var className = GetVCTHClassName(descriptor);
var className = context.GetClassName(tagHelper);
using (writer.BuildClassDeclaration(PublicModifiers, className, tagHelperTypeName, interfaces: null))
{
@ -114,10 +176,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
BuildConstructorString(writer, className);
// Add attributes.
BuildAttributeDeclarations(writer, descriptor);
BuildAttributeDeclarations(writer, tagHelper);
// Add process method.
BuildProcessMethodString(writer, descriptor);
BuildProcessMethodString(writer, tagHelper);
}
}
@ -136,7 +198,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
private void BuildAttributeDeclarations(CodeWriter writer, TagHelperDescriptor descriptor)
private void BuildAttributeDeclarations(CodeWriter writer, TagHelperDescriptor tagHelper)
{
writer.Write("[")
.Write("Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute")
@ -149,7 +211,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
$"global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext",
"ViewContext");
foreach (var attribute in descriptor.BoundAttributes)
foreach (var attribute in tagHelper.BoundAttributes)
{
writer.WriteAutoPropertyDeclaration(
PublicModifiers,
@ -165,7 +227,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
private void BuildProcessMethodString(CodeWriter writer, TagHelperDescriptor descriptor)
private void BuildProcessMethodString(CodeWriter writer, TagHelperDescriptor tagHelper)
{
var contextVariable = "context";
var outputVariable = "output";
@ -185,7 +247,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
"Contextualize",
new[] { "ViewContext" });
var methodParameters = GetMethodParameters(descriptor);
var methodParameters = GetMethodParameters(tagHelper);
var contentVariable = "content";
writer.Write("var ")
.WriteStartAssignment(contentVariable)
@ -199,22 +261,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
}
}
private string[] GetMethodParameters(TagHelperDescriptor descriptor)
private string[] GetMethodParameters(TagHelperDescriptor tagHelper)
{
var propertyNames = descriptor.BoundAttributes.Select(attribute => attribute.GetPropertyName());
var propertyNames = tagHelper.BoundAttributes.Select(attribute => attribute.GetPropertyName());
var joinedPropertyNames = string.Join(", ", propertyNames);
var parametersString = $"new {{ { joinedPropertyNames } }}";
var viewComponentName = descriptor.GetViewComponentName();
var viewComponentName = tagHelper.GetViewComponentName();
var methodParameters = new[] { $"\"{viewComponentName}\"", parametersString };
return methodParameters;
}
private void BuildTargetElementString(CodeWriter writer, TagHelperDescriptor descriptor)
private void BuildTargetElementString(CodeWriter writer, TagHelperDescriptor tagHelper)
{
Debug.Assert(descriptor.TagMatchingRules.Count() == 1);
Debug.Assert(tagHelper.TagMatchingRules.Count() == 1);
var rule = descriptor.TagMatchingRules.First();
var rule = tagHelper.TagMatchingRules.First();
writer.Write("[")
.WriteStartMethodInvocation("Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute")
@ -222,59 +283,59 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
.WriteLine(")]");
}
private class Visitor : IntermediateNodeWalker
private struct Context
{
public ClassDeclarationIntermediateNode Class { get; private set; }
private Dictionary<TagHelperDescriptor, (string className, string fullyQualifiedName, string fieldName)> _tagHelpers;
public DeclareTagHelperFieldsIntermediateNode Fields { get; private set; }
public NamespaceDeclarationIntermediateNode Namespace { get; private set; }
public List<IntermediateNodeReference> CreateTagHelpers { get; } = new List<IntermediateNodeReference>();
public Dictionary<string, TagHelperDescriptor> TagHelpers { get; } = new Dictionary<string, TagHelperDescriptor>();
public override void VisitCreateTagHelper(CreateTagHelperIntermediateNode node)
public Context(NamespaceDeclarationIntermediateNode @namespace, ClassDeclarationIntermediateNode @class)
{
var tagHelper = node.Descriptor;
if (tagHelper.IsViewComponentKind())
{
// Capture all the VCTagHelpers (unique by type name) so we can generate a class for each one.
var vcName = tagHelper.GetViewComponentName();
TagHelpers[vcName] = tagHelper;
Namespace = @namespace;
Class = @class;
CreateTagHelpers.Add(new IntermediateNodeReference(Parent, node));
}
_tagHelpers = new Dictionary<TagHelperDescriptor, (string, string, string)>();
}
public override void VisitNamespaceDeclaration(NamespaceDeclarationIntermediateNode node)
public ClassDeclarationIntermediateNode Class { get; }
public NamespaceDeclarationIntermediateNode Namespace { get; }
public IEnumerable<TagHelperDescriptor> TagHelpers => _tagHelpers.Keys;
public bool Add(TagHelperDescriptor tagHelper)
{
if (Namespace == null)
if (_tagHelpers.ContainsKey(tagHelper))
{
Namespace = node;
return false;
}
base.VisitNamespaceDeclaration(node);
var className = $"__Generated__{tagHelper.GetViewComponentName()}ViewComponentTagHelper";
var fullyQualifiedName = $"{Namespace.Content}.{Class.Name}.{className}";
var fieldName = GenerateFieldName(tagHelper);
_tagHelpers.Add(tagHelper, (className, fullyQualifiedName, fieldName));
return true;
}
public override void VisitClassDeclaration(ClassDeclarationIntermediateNode node)
public string GetClassName(TagHelperDescriptor taghelper)
{
if (Class == null)
{
Class = node;
}
base.VisitClassDeclaration(node);
return _tagHelpers[taghelper].className;
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIntermediateNode node)
public string GetFullyQualifiedName(TagHelperDescriptor taghelper)
{
if (Fields == null)
{
Fields = node;
}
return _tagHelpers[taghelper].fullyQualifiedName;
}
base.VisitDeclareTagHelperFields(node);
public string GetFieldName(TagHelperDescriptor taghelper)
{
return _tagHelpers[taghelper].fieldName;
}
private static string GenerateFieldName(TagHelperDescriptor tagHelper)
{
return $"__{tagHelper.GetViewComponentName()}ViewComponentTagHelper";
}
}
}

View File

@ -7,16 +7,25 @@ namespace Microsoft.AspNetCore.Razor.Language
{
public static class BoundAttributeDescriptorExtensions
{
public static string GetPropertyName(this BoundAttributeDescriptor descriptor)
public static string GetPropertyName(this BoundAttributeDescriptor attribute)
{
descriptor.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName);
if (attribute == null)
{
throw new ArgumentNullException(nameof(attribute));
}
attribute.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName);
return propertyName;
}
public static bool IsDefaultKind(this BoundAttributeDescriptor descriptor)
public static bool IsDefaultKind(this BoundAttributeDescriptor attribute)
{
return string.Equals(descriptor.Kind, TagHelperConventions.DefaultKind, StringComparison.Ordinal);
if (attribute == null)
{
throw new ArgumentNullException(nameof(attribute));
}
return string.Equals(attribute.Kind, TagHelperConventions.DefaultKind, StringComparison.Ordinal);
}
}
}

View File

@ -582,15 +582,15 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
return new CSharpCodeWritingScope(this);
}
public IDisposable BuildLinePragma(SourceSpan documentLocation)
public IDisposable BuildLinePragma(SourceSpan? span)
{
if (string.IsNullOrEmpty(documentLocation.FilePath))
if (string.IsNullOrEmpty(span?.FilePath))
{
// Can't build a valid line pragma without a file path.
return NullDisposable.Default;
}
return new LinePragmaWriter(this, documentLocation);
return new LinePragmaWriter(this, span.Value);
}
private void WriteVerbatimStringLiteral(string literal)

View File

@ -203,11 +203,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Context.NodeWriter.WriteHtmlContent(Context, node);
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIntermediateNode node)
{
Context.TagHelperWriter.WriteDeclareTagHelperFields(Context, node);
}
public override void VisitTagHelper(TagHelperIntermediateNode node)
{
var tagHelperRenderingContext = new TagHelperRenderingContext()
@ -218,30 +213,10 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
using (Context.Push(tagHelperRenderingContext))
{
Context.TagHelperWriter.WriteTagHelper(Context, node);
RenderChildren(node);
}
}
public override void VisitTagHelperBody(TagHelperBodyIntermediateNode node)
{
Context.TagHelperWriter.WriteTagHelperBody(Context, node);
}
public override void VisitCreateTagHelper(CreateTagHelperIntermediateNode node)
{
Context.TagHelperWriter.WriteCreateTagHelper(Context, node);
}
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIntermediateNode node)
{
Context.TagHelperWriter.WriteAddTagHelperHtmlAttribute(Context, node);
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIntermediateNode node)
{
Context.TagHelperWriter.WriteSetTagHelperProperty(Context, node);
}
public override void VisitDefault(IntermediateNode node)
{
Context.RenderChildren(node);

View File

@ -12,209 +12,5 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class DesignTimeTagHelperWriter : TagHelperWriter
{
public string CreateTagHelperMethodName { get; set; } = "CreateTagHelper";
public override void WriteDeclareTagHelperFields(CodeRenderingContext context, DeclareTagHelperFieldsIntermediateNode node)
{
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
context.CodeWriter
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
public override void WriteTagHelper(CodeRenderingContext context, TagHelperIntermediateNode node)
{
context.RenderChildren(node);
}
public override void WriteTagHelperBody(CodeRenderingContext context, TagHelperBodyIntermediateNode node)
{
context.RenderChildren(node);
}
public override void WriteCreateTagHelper(CodeRenderingContext context, CreateTagHelperIntermediateNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
context.CodeWriter
.WriteStartAssignment(tagHelperVariableName)
.Write(CreateTagHelperMethodName)
.WriteLine($"<global::{node.TagHelperTypeName}>();");
}
public override void WriteAddTagHelperHtmlAttribute(CodeRenderingContext context, AddTagHelperHtmlAttributeIntermediateNode node)
{
context.RenderChildren(node);
}
public override void WriteSetTagHelperProperty(CodeRenderingContext context, SetTagHelperPropertyIntermediateNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var tagHelperRenderingContext = context.TagHelperRenderingContext;
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
if (tagHelperRenderingContext.RenderedBoundAttributes.TryGetValue(node.AttributeName, out string previousValueAccessor))
{
context.CodeWriter
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty))
{
context.RenderChildren(node);
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
if (node.Children.Count == 1 && node.Children.First() is HtmlContentIntermediateNode htmlNode)
{
var content = GetContent(htmlNode);
context.CodeWriter.WriteStringLiteral(content);
}
else
{
context.CodeWriter.Write("string.Empty");
}
context.CodeWriter.WriteLine(";");
}
else
{
var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as IntermediateNode;
var valueStart = firstMappedChild?.Source;
using (context.CodeWriter.BuildLinePragma(node.Source.Value))
{
var assignmentPrefixLength = propertyValueAccessor.Length + " = ".Length;
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is IntermediateToken token &&
token.IsCSharp)
{
assignmentPrefixLength += $"global::{node.Descriptor.TypeName}.".Length;
if (valueStart != null)
{
context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source.Value, context);
}
context.CodeWriter
.WriteStartAssignment(propertyValueAccessor)
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
else
{
if (valueStart != null)
{
context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source.Value, context);
}
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
}
RenderTagHelperAttributeInline(context, node, node.Source.Value);
context.CodeWriter.WriteLine(";");
}
}
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
SetTagHelperPropertyIntermediateNode property,
SourceSpan documentLocation)
{
for (var i = 0; i < property.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, property.Children[i], documentLocation);
}
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
SetTagHelperPropertyIntermediateNode property,
IntermediateNode node,
SourceSpan documentLocation)
{
if (node is CSharpExpressionIntermediateNode || node is HtmlContentIntermediateNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, node.Children[i], documentLocation);
}
}
else if (node is IntermediateToken token)
{
if (node.Source != null)
{
context.AddLineMappingFor(node);
}
context.CodeWriter.Write(token.Content);
}
else if (node is CSharpCodeIntermediateNode)
{
var error = new RazorError(
LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes,
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
else if (node is TemplateIntermediateNode)
{
var expectedTypeName = property.IsIndexerNameMatch ? property.Descriptor.IndexerTypeName : property.Descriptor.TypeName;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(expectedTypeName),
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
}
private string GetContent(HtmlContentIntermediateNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is IntermediateToken token && token.IsHtml)
{
builder.Append(token.Content);
}
}
return builder.ToString();
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
private static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,
string attributeName,
BoundAttributeDescriptor descriptor)
{
var propertyAccessor = $"{tagHelperVariableName}.{descriptor.GetPropertyName()}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
}
}

View File

@ -142,7 +142,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
var suffixLocation = node.Source.Value.AbsoluteIndex + node.Source.Value.Length - node.Suffix.Length;
context.CodeWriter
.WriteStartMethodInvocation(BeginWriteAttributeMethod)
.WriteStringLiteral(node.Name)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()

View File

@ -12,484 +12,5 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class RuntimeTagHelperWriter : TagHelperWriter
{
public virtual string WriteTagHelperOutputMethod { get; set; } = "Write";
public string StringValueBufferVariableName { get; set; } = "__tagHelperStringValueBuffer";
public string ExecutionContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext";
public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext";
public string ExecutionContextAddMethodName { get; set; } = "Add";
public string ExecutionContextOutputPropertyName { get; set; } = "Output";
public string ExecutionContextSetOutputContentAsyncMethodName { get; set; } = "SetOutputContentAsync";
public string ExecutionContextAddHtmlAttributeMethodName { get; set; } = "AddHtmlAttribute";
public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute";
public string RunnerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner";
public string RunnerVariableName { get; set; } = "__tagHelperRunner";
public string RunnerRunAsyncMethodName { get; set; } = "RunAsync";
public string ScopeManagerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager";
public string ScopeManagerVariableName { get; set; } = "__tagHelperScopeManager";
public string ScopeManagerBeginMethodName { get; set; } = "Begin";
public string ScopeManagerEndMethodName { get; set; } = "End";
public string StartTagHelperWritingScopeMethodName { get; set; } = "StartTagHelperWritingScope";
public string EndTagHelperWritingScopeMethodName { get; set; } = "EndTagHelperWritingScope";
public string TagModeTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode";
public string HtmlAttributeValueStyleTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle";
public string CreateTagHelperMethodName { get; set; } = "CreateTagHelper";
public string TagHelperOutputIsContentModifiedPropertyName { get; set; } = "IsContentModified";
public string BeginAddHtmlAttributeValuesMethodName { get; set; } = "BeginAddHtmlAttributeValues";
public string EndAddHtmlAttributeValuesMethodName { get; set; } = "EndAddHtmlAttributeValues";
public string BeginWriteTagHelperAttributeMethodName { get; set; } = "BeginWriteTagHelperAttribute";
public string EndWriteTagHelperAttributeMethodName { get; set; } = "EndWriteTagHelperAttribute";
public string MarkAsHtmlEncodedMethodName { get; set; } = "Html.Raw";
public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment";
public override void WriteDeclareTagHelperFields(CodeRenderingContext context, DeclareTagHelperFieldsIntermediateNode node)
{
context.CodeWriter.WriteLine("#line hidden");
// Need to disable the warning "X is assigned to but never used." for the value buffer since
// whether it's used depends on how a TagHelper is used.
context.CodeWriter
.WriteLine("#pragma warning disable 0414")
.Write("private ")
.WriteVariableDeclaration("string", StringValueBufferVariableName, value: null)
.WriteLine("#pragma warning restore 0414");
context.CodeWriter
.Write("private ")
.WriteVariableDeclaration(
ExecutionContextTypeName,
ExecutionContextVariableName,
value: null);
context.CodeWriter
.Write("private ")
.Write(RunnerTypeName)
.Write(" ")
.Write(RunnerVariableName)
.Write(" = new ")
.Write(RunnerTypeName)
.WriteLine("();");
var backedScopeManageVariableName = "__backed" + ScopeManagerVariableName;
context.CodeWriter
.Write("private ")
.WriteVariableDeclaration(
ScopeManagerTypeName,
backedScopeManageVariableName,
value: null);
context.CodeWriter
.Write("private ")
.Write(ScopeManagerTypeName)
.Write(" ")
.WriteLine(ScopeManagerVariableName);
using (context.CodeWriter.BuildScope())
{
context.CodeWriter.WriteLine("get");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.Write("if (")
.Write(backedScopeManageVariableName)
.WriteLine(" == null)");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.WriteStartAssignment(backedScopeManageVariableName)
.WriteStartNewObject(ScopeManagerTypeName)
.Write(StartTagHelperWritingScopeMethodName)
.WriteParameterSeparator()
.Write(EndTagHelperWritingScopeMethodName)
.WriteEndMethodInvocation();
}
context.CodeWriter
.Write("return ")
.Write(backedScopeManageVariableName)
.WriteLine(";");
}
}
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
context.CodeWriter
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
public override void WriteTagHelper(CodeRenderingContext context, TagHelperIntermediateNode node)
{
context.RenderChildren(node);
// Execute tag helpers
context.CodeWriter
.Write("await ")
.WriteStartInstanceMethodInvocation(
RunnerVariableName,
RunnerRunAsyncMethodName)
.Write(ExecutionContextVariableName)
.WriteEndMethodInvocation();
var tagHelperOutputAccessor = $"{ExecutionContextVariableName}.{ExecutionContextOutputPropertyName}";
context.CodeWriter
.Write("if (!")
.Write(tagHelperOutputAccessor)
.Write(".")
.Write(TagHelperOutputIsContentModifiedPropertyName)
.WriteLine(")");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.Write("await ")
.WriteInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextSetOutputContentAsyncMethodName);
}
context.CodeWriter
.WriteStartMethodInvocation(WriteTagHelperOutputMethod)
.Write(tagHelperOutputAccessor)
.WriteEndMethodInvocation()
.WriteStartAssignment(ExecutionContextVariableName)
.WriteInstanceMethodInvocation(
ScopeManagerVariableName,
ScopeManagerEndMethodName);
}
public override void WriteTagHelperBody(CodeRenderingContext context, TagHelperBodyIntermediateNode node)
{
// Call into the tag helper scope manager to start a new tag helper scope.
// Also capture the value as the current execution context.
context.CodeWriter
.WriteStartAssignment(ExecutionContextVariableName)
.WriteStartInstanceMethodInvocation(
ScopeManagerVariableName,
ScopeManagerBeginMethodName);
var uniqueId = context.Items[CodeRenderingContext.SuppressUniqueIds]?.ToString();
if (uniqueId == null)
{
uniqueId = Guid.NewGuid().ToString("N");
}
// Assign a unique ID for this instance of the source HTML tag. This must be unique
// per call site, e.g. if the tag is on the view twice, there should be two IDs.
context.CodeWriter.WriteStringLiteral(context.TagHelperRenderingContext.TagName)
.WriteParameterSeparator()
.Write(TagModeTypeName)
.Write(".")
.Write(context.TagHelperRenderingContext.TagMode.ToString())
.WriteParameterSeparator()
.WriteStringLiteral(uniqueId)
.WriteParameterSeparator();
// We remove and redirect writers so TagHelper authors can retrieve content.
using (context.Push(new RuntimeNodeWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
using (context.CodeWriter.BuildAsyncLambda())
{
context.RenderChildren(node);
}
}
context.CodeWriter.WriteEndMethodInvocation();
}
public override void WriteCreateTagHelper(CodeRenderingContext context, CreateTagHelperIntermediateNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
context.CodeWriter
.WriteStartAssignment(tagHelperVariableName)
.Write(CreateTagHelperMethodName)
.WriteLine($"<global::{node.TagHelperTypeName}>();");
context.CodeWriter.WriteInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddMethodName,
tagHelperVariableName);
}
public override void WriteAddTagHelperHtmlAttribute(CodeRenderingContext context, AddTagHelperHtmlAttributeIntermediateNode node)
{
var attributeValueStyleParameter = $"{HtmlAttributeValueStyleTypeName}.{node.AttributeStructure}";
var isConditionalAttributeValue = node.Children.Any(
child => child is CSharpExpressionAttributeValueIntermediateNode || child is CSharpCodeAttributeValueIntermediateNode);
// All simple text and minimized attributes will be pre-allocated.
if (isConditionalAttributeValue)
{
// Dynamic attribute value should be run through the conditional attribute removal system. It's
// unbound and contains C#.
// TagHelper attribute rendering is buffered by default. We do not want to write to the current
// writer.
var valuePieceCount = node.Children.Count(
child =>
child is HtmlAttributeValueIntermediateNode ||
child is CSharpExpressionAttributeValueIntermediateNode ||
child is CSharpCodeAttributeValueIntermediateNode ||
child is ExtensionIntermediateNode);
context.CodeWriter
.WriteStartMethodInvocation(BeginAddHtmlAttributeValuesMethodName)
.Write(ExecutionContextVariableName)
.WriteParameterSeparator()
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(attributeValueStyleParameter)
.WriteEndMethodInvocation();
using (context.Push(new TagHelperHtmlAttributeRuntimeNodeWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteMethodInvocation(
EndAddHtmlAttributeValuesMethodName,
ExecutionContextVariableName);
}
else
{
// This is a data-* attribute which includes C#. Do not perform the conditional attribute removal or
// other special cases used when IsDynamicAttributeValue(). But the attribute must still be buffered to
// determine its final value.
// Attribute value is not plain text, must be buffered to determine its final value.
context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);
// We're building a writing scope around the provided chunks which captures everything written from the
// page. Therefore, we do not want to write to any other buffer since we're using the pages buffer to
// ensure we capture all content that's written, directly or indirectly.
using (context.Push(new RuntimeNodeWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteStartAssignment(StringValueBufferVariableName)
.WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
.WriteStartInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddHtmlAttributeMethodName)
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStartMethodInvocation(MarkAsHtmlEncodedMethodName)
.Write(StringValueBufferVariableName)
.WriteEndMethodInvocation(endLine: false)
.WriteParameterSeparator()
.Write(attributeValueStyleParameter)
.WriteEndMethodInvocation();
}
}
public override void WriteSetTagHelperProperty(CodeRenderingContext context, SetTagHelperPropertyIntermediateNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var tagHelperRenderingContext = context.TagHelperRenderingContext;
var propertyName = node.Descriptor.GetPropertyName();
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelperTypeName}.{propertyName}"))
{
// Throw a reasonable Exception at runtime if the dictionary property is null.
context.CodeWriter
.Write("if (")
.Write(tagHelperVariableName)
.Write(".")
.Write(propertyName)
.WriteLine(" == null)");
using (context.CodeWriter.BuildScope())
{
// System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName
// of InvalidOperationException type.
context.CodeWriter
.Write("throw ")
.WriteStartNewObject(nameof(InvalidOperationException))
.WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStringLiteral(node.TagHelperTypeName)
.WriteParameterSeparator()
.WriteStringLiteral(propertyName)
.WriteEndMethodInvocation(endLine: false) // End of method call
.WriteEndMethodInvocation(); // End of new expression / throw statement
}
}
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
if (tagHelperRenderingContext.RenderedBoundAttributes.TryGetValue(node.AttributeName, out var previousValueAccessor))
{
context.CodeWriter
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty))
{
context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);
using (context.Push(new LiteralRuntimeNodeWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteStartAssignment(StringValueBufferVariableName)
.WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
.WriteStartAssignment(propertyValueAccessor)
.Write(StringValueBufferVariableName)
.WriteLine(";");
}
else
{
using (context.CodeWriter.BuildLinePragma(node.Source.Value))
{
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is IntermediateToken token &&
token.IsCSharp)
{
context.CodeWriter
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
RenderTagHelperAttributeInline(context, node, node.Source.Value);
context.CodeWriter.WriteLine(";");
}
}
// We need to inform the context of the attribute value.
context.CodeWriter
.WriteStartInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddTagHelperAttributeMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.Write(propertyValueAccessor)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.AttributeStructure}")
.WriteEndMethodInvocation();
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
SetTagHelperPropertyIntermediateNode property,
SourceSpan documentLocation)
{
for (var i = 0; i < property.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, property.Children[i], documentLocation);
}
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
SetTagHelperPropertyIntermediateNode property,
IntermediateNode node,
SourceSpan documentLocation)
{
if (node is CSharpExpressionIntermediateNode || node is HtmlContentIntermediateNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, node.Children[i], documentLocation);
}
}
else if (node is IntermediateToken token)
{
context.CodeWriter.Write(token.Content);
}
else if (node is CSharpCodeIntermediateNode)
{
var error = new RazorError(
LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes,
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
else if (node is TemplateIntermediateNode)
{
var expectedTypeName = property.IsIndexerNameMatch ? property.Descriptor.IndexerTypeName : property.Descriptor.TypeName;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(expectedTypeName),
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
}
protected static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,
string attributeName,
BoundAttributeDescriptor descriptor)
{
var propertyAccessor = $"{tagHelperVariableName}.{descriptor.GetPropertyName()}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
}
}

View File

@ -7,16 +7,5 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal abstract class TagHelperWriter
{
public abstract void WriteDeclareTagHelperFields(CodeRenderingContext context, DeclareTagHelperFieldsIntermediateNode node);
public abstract void WriteTagHelper(CodeRenderingContext context, TagHelperIntermediateNode node);
public abstract void WriteTagHelperBody(CodeRenderingContext context, TagHelperBodyIntermediateNode node);
public abstract void WriteCreateTagHelper(CodeRenderingContext context, CreateTagHelperIntermediateNode node);
public abstract void WriteAddTagHelperHtmlAttribute(CodeRenderingContext context, AddTagHelperHtmlAttributeIntermediateNode node);
public abstract void WriteSetTagHelperProperty(CodeRenderingContext context, SetTagHelperPropertyIntermediateNode node);
}
}

View File

@ -44,6 +44,16 @@ namespace Microsoft.AspNetCore.Razor.Language
public override bool IsReadOnly => false;
public override void Add(object key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
_items.Add(key, value);
}
public override void Add(KeyValuePair<object, object> item)
{
if (item.Key == null)

View File

@ -362,7 +362,6 @@ namespace Microsoft.AspNetCore.Razor.Language
private class MainSourceVisitor : LoweringVisitor
{
private DeclareTagHelperFieldsIntermediateNode _tagHelperFields;
private readonly string _tagHelperPrefix;
public MainSourceVisitor(DocumentIntermediateNode document, IntermediateNodeBuilder builder, Dictionary<string, SourceSpan?> namespaces, string tagHelperPrefix)
@ -380,7 +379,7 @@ namespace Microsoft.AspNetCore.Razor.Language
{
_builder.Push(new HtmlAttributeIntermediateNode()
{
Name = chunkGenerator.Name,
AttributeName = chunkGenerator.Name,
Prefix = chunkGenerator.Prefix,
Suffix = chunkGenerator.Suffix,
Source = BuildSourceSpanFromNode(block),
@ -619,8 +618,6 @@ namespace Microsoft.AspNetCore.Razor.Language
return;
}
DeclareTagHelperFields(tagHelperBlock);
var tagName = tagHelperBlock.TagName;
if (_tagHelperPrefix != null)
{
@ -647,7 +644,6 @@ namespace Microsoft.AspNetCore.Razor.Language
_builder.Pop(); // Pop InitializeTagHelperStructureIntermediateNode
AddTagHelperCreation(tagHelperBlock.Binding);
AddTagHelperAttributes(tagHelperBlock.Attributes, tagHelperBlock.Binding);
_builder.Pop(); // Pop TagHelperIntermediateNode
@ -675,37 +671,6 @@ namespace Microsoft.AspNetCore.Razor.Language
}
}
private void DeclareTagHelperFields(TagHelperBlock block)
{
if (_tagHelperFields == null)
{
_tagHelperFields = new DeclareTagHelperFieldsIntermediateNode();
_document.Children.Add(_tagHelperFields);
}
foreach (var descriptor in block.Binding.Descriptors)
{
var typeName = descriptor.GetTypeName();
_tagHelperFields.UsedTagHelperTypeNames.Add(typeName);
}
}
private void AddTagHelperCreation(TagHelperBinding tagHelperBinding)
{
var descriptors = tagHelperBinding.Descriptors;
foreach (var descriptor in descriptors)
{
var typeName = descriptor.GetTypeName();
var createTagHelper = new CreateTagHelperIntermediateNode()
{
TagHelperTypeName = typeName,
Descriptor = descriptor
};
_builder.Add(createTagHelper);
}
}
private void AddTagHelperAttributes(IList<TagHelperAttributeNode> attributes, TagHelperBinding tagHelperBinding)
{
var descriptors = tagHelperBinding.Descriptors;
@ -727,18 +692,16 @@ namespace Microsoft.AspNetCore.Razor.Language
foreach (var associatedDescriptor in associatedDescriptors)
{
var associatedAttributeDescriptor = associatedDescriptor.BoundAttributes.First(
attributeDescriptor => TagHelperMatchingConventions.CanSatisfyBoundAttribute(attribute.Name, attributeDescriptor));
var tagHelperTypeName = associatedDescriptor.GetTypeName();
var attributePropertyName = associatedAttributeDescriptor.GetPropertyName();
var setTagHelperProperty = new SetTagHelperPropertyIntermediateNode()
var associatedAttributeDescriptor = associatedDescriptor.BoundAttributes.First(a =>
{
return TagHelperMatchingConventions.CanSatisfyBoundAttribute(attribute.Name, a);
});
var setTagHelperProperty = new TagHelperPropertyIntermediateNode()
{
PropertyName = attributePropertyName,
AttributeName = attribute.Name,
TagHelperTypeName = tagHelperTypeName,
Descriptor = associatedAttributeDescriptor,
Binding = tagHelperBinding,
BoundAttribute = associatedAttributeDescriptor,
TagHelper = associatedDescriptor,
AttributeStructure = attribute.AttributeStructure,
Source = BuildSourceSpanFromNode(attributeValueNode),
IsIndexerNameMatch = TagHelperMatchingConventions.SatisfiesBoundAttributeIndexer(attribute.Name, associatedAttributeDescriptor),
@ -751,9 +714,9 @@ namespace Microsoft.AspNetCore.Razor.Language
}
else
{
var addHtmlAttribute = new AddTagHelperHtmlAttributeIntermediateNode()
var addHtmlAttribute = new TagHelperHtmlAttributeIntermediateNode()
{
Name = attribute.Name,
AttributeName = attribute.Name,
AttributeStructure = attribute.AttributeStructure
};

View File

@ -24,6 +24,10 @@ namespace Microsoft.AspNetCore.Razor.Language
AssemblyName = assemblyName;
_metadata = new Dictionary<string, string>(StringComparer.Ordinal);
// Tells code generation that these tag helpers are compatible with ITagHelper.
// For now that's all we support.
_metadata.Add(TagHelperMetadata.Runtime.Name, TagHelperConventions.DefaultKind);
}
public override string Name { get; }

View File

@ -139,11 +139,6 @@ namespace Microsoft.AspNetCore.Razor.Language
_namespace.Insert(i + 1, node);
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIntermediateNode node)
{
_class.Insert(0, node);
}
public override void VisitDefault(IntermediateNode node)
{
if (node is MemberDeclarationIntermediateNode)

View File

@ -0,0 +1,70 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperBodyIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = new DefaultIntermediateNodeCollection();
public DefaultTagHelperBodyIntermediateNode()
{
}
public DefaultTagHelperBodyIntermediateNode(TagHelperBodyIntermediateNode bodyNode)
{
if (bodyNode == null)
{
throw new ArgumentNullException(nameof(bodyNode));
}
Source = bodyNode.Source;
for (var i = 0; i < bodyNode.Children.Count; i++)
{
Children.Add(bodyNode.Children[i]);
}
for (var i = 0; i < bodyNode.Diagnostics.Count; i++)
{
Diagnostics.Add(bodyNode.Diagnostics[i]);
}
}
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperBodyIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperBody(context, this);
}
}
}

View File

@ -0,0 +1,52 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperCreateIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = ReadOnlyIntermediateNodeCollection.Instance;
public string Field { get; set; }
public TagHelperDescriptor TagHelper { get; set; }
public string Type { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperCreateIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperCreate(context, this);
}
}
}

View File

@ -0,0 +1,46 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperExecuteIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = ReadOnlyIntermediateNodeCollection.Instance;
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperExecuteIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperExecute(context, this);
}
}
}

View File

@ -0,0 +1,76 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode
{
public DefaultTagHelperHtmlAttributeIntermediateNode()
{
}
public DefaultTagHelperHtmlAttributeIntermediateNode(TagHelperHtmlAttributeIntermediateNode htmlAttributeNode)
{
if (htmlAttributeNode == null)
{
throw new ArgumentNullException(nameof(htmlAttributeNode));
}
AttributeName = htmlAttributeNode.AttributeName;
AttributeStructure = htmlAttributeNode.AttributeStructure;
Source = htmlAttributeNode.Source;
for (var i = 0; i < htmlAttributeNode.Children.Count; i++)
{
Children.Add(htmlAttributeNode.Children[i]);
}
for (var i = 0; i < htmlAttributeNode.Diagnostics.Count; i++)
{
Diagnostics.Add(htmlAttributeNode.Diagnostics[i]);
}
}
public string AttributeName { get; set; }
public AttributeStructure AttributeStructure { get; set; }
public override IntermediateNodeCollection Children { get; } = new DefaultIntermediateNodeCollection();
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperHtmlAttributeIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperHtmlAttribute(context, this);
}
}
}

View File

@ -0,0 +1,255 @@
// 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.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal class DefaultTagHelperOptimizationPass : IntermediateNodePassBase, IRazorOptimizationPass
{
// Run later than default order for user code so other passes have a chance to modify the
// tag helper nodes.
public override int Order => DefaultFeatureOrder + 1000;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
var @class = documentNode.FindPrimaryClass();
if (@class == null)
{
// Bail if we can't find a class node, we need to be able to create fields.
return;
}
var context = new Context(@class);
// First find all tag helper nodes that require the default tag helper runtime.
//
// This phase lowers the conceptual nodes to default runtime nodes we only care about those.
var tagHelperNodes = documentNode
.FindDescendantNodes<TagHelperIntermediateNode>()
.Where(IsTagHelperRuntimeNode)
.ToArray();
if (tagHelperNodes.Length == 0)
{
// If nothing uses the default runtime then we're done.
return;
}
AddDefaultRuntime(context);
// Each tagHelperNode should be rewritten to use the default tag helper runtime. That doesn't necessarily
// mean that all of these tag helpers are the default kind, just that them are compatible with ITagHelper.
for (var i = 0; i < tagHelperNodes.Length; i++)
{
var tagHelperNode = tagHelperNodes[i];
RewriteBody(tagHelperNode);
RewriteHtmlAttributes(tagHelperNode);
AddExecute(tagHelperNode);
// We need to find all of the 'default' kind tag helpers and rewrite their usage site to use the
// extension nodes for the default tag helper runtime (ITagHelper).
foreach (var tagHelper in tagHelperNode.TagHelpers)
{
RewriteUsage(context, tagHelperNode, tagHelper);
}
}
// Then for each 'default' kind tag helper we need to generate the field that will hold it.
foreach (var tagHelper in context.TagHelpers)
{
AddField(context, tagHelper);
}
}
private void AddDefaultRuntime(Context context)
{
// We need to insert a node for the field that will hold the tag helper. We've already generated a field name
// at this time and use it for all uses of the same tag helper type.
//
// We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing
// field nodes.
var i = 0;
while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode)
{
i++;
}
context.Class.Children.Insert(i, new DefaultTagHelperRuntimeIntermediateNode());
}
private void RewriteBody(TagHelperIntermediateNode node)
{
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is TagHelperBodyIntermediateNode bodyNode)
{
// We only expect one body node.
node.Children[i] = new DefaultTagHelperBodyIntermediateNode(bodyNode);
break;
}
}
}
private void AddExecute(TagHelperIntermediateNode node)
{
// Execute the tag helpers at the end, before leaving scope.
node.Children.Add(new DefaultTagHelperExecuteIntermediateNode());
}
private void RewriteHtmlAttributes(TagHelperIntermediateNode node)
{
// We need to rewrite each html attribute, so that it will get added to the execution context.
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is TagHelperHtmlAttributeIntermediateNode htmlAttributeNode)
{
node.Children[i] = new DefaultTagHelperHtmlAttributeIntermediateNode(htmlAttributeNode);
}
}
}
private void RewriteUsage(Context context, TagHelperIntermediateNode node, TagHelperDescriptor tagHelper)
{
if (!tagHelper.IsDefaultKind())
{
return;
}
context.Add(tagHelper);
// First we need to insert a node for the creation of the tag helper, and the hook up to the execution
// context. This should come after the body node and any existing create nodes.
//
// If we're dealing with something totally malformed, then we'll end up just inserting at the end, and that's not
// so bad.
var i = 0;
// Find the body node.
while (i < node.Children.Count && node.Children[i] is TagHelperBodyIntermediateNode)
{
i++;
}
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperBodyIntermediateNode)
{
i++;
}
// Now find the last create node.
while (i < node.Children.Count && node.Children[i] is DefaultTagHelperCreateIntermediateNode)
{
i++;
}
// Now i has the right insertion point.
node.Children.Insert(i, new DefaultTagHelperCreateIntermediateNode()
{
Field = context.GetFieldName(tagHelper),
TagHelper = tagHelper,
Type = tagHelper.GetTypeName(),
});
// Next we need to rewrite any property nodes to use the field and property name for this
// tag helper.
for (i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is TagHelperPropertyIntermediateNode propertyNode &&
propertyNode.TagHelper == tagHelper)
{
// This belongs to the current tag helper, replace it.
node.Children[i] = new DefaultTagHelperPropertyIntermediateNode(propertyNode)
{
Field = context.GetFieldName(tagHelper),
Property = propertyNode.BoundAttribute.GetPropertyName(),
};
}
}
}
private void AddField(Context context, TagHelperDescriptor tagHelper)
{
// We need to insert a node for the field that will hold the tag helper. We've already generated a field name
// at this time and use it for all uses of the same tag helper type.
//
// We also want to preserve the ordering of the nodes for testability. So insert at the end of any existing
// field nodes.
var i = 0;
while (i < context.Class.Children.Count && context.Class.Children[i] is DefaultTagHelperRuntimeIntermediateNode)
{
i++;
}
while (i < context.Class.Children.Count && context.Class.Children[i] is FieldDeclarationIntermediateNode)
{
i++;
}
context.Class.Children.Insert(i, new FieldDeclarationIntermediateNode()
{
Annotations =
{
{ CommonAnnotations.DefaultTagHelperExtension.TagHelperField, bool.TrueString },
},
Modifiers =
{
"private",
},
Name = context.GetFieldName(tagHelper),
Type = "global::" + tagHelper.GetTypeName(),
});
}
private bool IsTagHelperRuntimeNode(TagHelperIntermediateNode node)
{
foreach (var tagHelper in node.TagHelpers)
{
if (tagHelper.KindUsesDefaultTagHelperRuntime())
{
return true;
}
}
return false;
}
private struct Context
{
private readonly Dictionary<TagHelperDescriptor, string> _tagHelpers;
public Context(ClassDeclarationIntermediateNode @class)
{
Class = @class;
_tagHelpers = new Dictionary<TagHelperDescriptor, string>(TagHelperDescriptorComparer.Default);
}
public ClassDeclarationIntermediateNode Class { get; }
public IEnumerable<TagHelperDescriptor> TagHelpers => _tagHelpers.Keys;
public bool Add(TagHelperDescriptor tagHelper)
{
if (_tagHelpers.ContainsKey(tagHelper))
{
return false;
}
_tagHelpers.Add(tagHelper, GenerateFieldName(tagHelper));
return true;
}
public string GetFieldName(TagHelperDescriptor tagHelper)
{
return _tagHelpers[tagHelper];
}
private static string GenerateFieldName(TagHelperDescriptor tagHelper)
{
return "__" + tagHelper.GetTypeName().Replace('.', '_');
}
}
}
}

View File

@ -0,0 +1,89 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperPropertyIntermediateNode : ExtensionIntermediateNode
{
public DefaultTagHelperPropertyIntermediateNode()
{
}
public DefaultTagHelperPropertyIntermediateNode(TagHelperPropertyIntermediateNode propertyNode)
{
if (propertyNode == null)
{
throw new ArgumentNullException(nameof(propertyNode));
}
AttributeName = propertyNode.AttributeName;
AttributeStructure = propertyNode.AttributeStructure;
BoundAttribute = propertyNode.BoundAttribute;
IsIndexerNameMatch = propertyNode.IsIndexerNameMatch;
Source = propertyNode.Source;
TagHelper = propertyNode.TagHelper;
for (var i = 0; i < propertyNode.Children.Count; i++)
{
Children.Add(propertyNode.Children[i]);
}
for (var i = 0; i < propertyNode.Diagnostics.Count; i++)
{
Diagnostics.Add(propertyNode.Diagnostics[i]);
}
}
public override IntermediateNodeCollection Children { get; } = new DefaultIntermediateNodeCollection();
public string AttributeName { get; set; }
public AttributeStructure AttributeStructure { get; set; }
public BoundAttributeDescriptor BoundAttribute { get; set; }
public string Field { get; set; }
public bool IsIndexerNameMatch { get; set; }
public string Property { get; set; }
public TagHelperDescriptor TagHelper { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperPropertyIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperProperty(context, this);
}
}
}

View File

@ -0,0 +1,46 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public sealed class DefaultTagHelperRuntimeIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = new DefaultIntermediateNodeCollection();
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DefaultTagHelperRuntimeIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var extension = target.GetExtension<IDefaultTagHelperTargetExtension>();
if (extension == null)
{
ReportMissingCodeTargetExtension<IDefaultTagHelperTargetExtension>(context);
return;
}
extension.WriteTagHelperRuntime(context, this);
}
}
}

View File

@ -0,0 +1,584 @@
// 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.Globalization;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class DefaultTagHelperTargetExtension : IDefaultTagHelperTargetExtension
{
private static readonly string[] PrivateModifiers = new string[] { "private" };
public bool DesignTime { get; set; }
public string RunnerVariableName { get; set; } = "__tagHelperRunner";
public string StringValueBufferVariableName { get; set; } = "__tagHelperStringValueBuffer";
public string CreateTagHelperMethodName { get; set; } = "CreateTagHelper";
public string ExecutionContextTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext";
public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext";
public string ExecutionContextAddMethodName { get; set; } = "Add";
public string TagHelperRunnerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner";
public string ExecutionContextOutputPropertyName { get; set; } = "Output";
public string ExecutionContextSetOutputContentAsyncMethodName { get; set; } = "SetOutputContentAsync";
public string ExecutionContextAddHtmlAttributeMethodName { get; set; } = "AddHtmlAttribute";
public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute";
public string RunnerRunAsyncMethodName { get; set; } = "RunAsync";
public string ScopeManagerTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager";
public string ScopeManagerVariableName { get; set; } = "__tagHelperScopeManager";
public string ScopeManagerBeginMethodName { get; set; } = "Begin";
public string ScopeManagerEndMethodName { get; set; } = "End";
public string StartTagHelperWritingScopeMethodName { get; set; } = "StartTagHelperWritingScope";
public string EndTagHelperWritingScopeMethodName { get; set; } = "EndTagHelperWritingScope";
public string TagModeTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode";
public string HtmlAttributeValueStyleTypeName { get; set; } = "global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle";
public string TagHelperOutputIsContentModifiedPropertyName { get; set; } = "IsContentModified";
public string BeginAddHtmlAttributeValuesMethodName { get; set; } = "BeginAddHtmlAttributeValues";
public string EndAddHtmlAttributeValuesMethodName { get; set; } = "EndAddHtmlAttributeValues";
public string BeginWriteTagHelperAttributeMethodName { get; set; } = "BeginWriteTagHelperAttribute";
public string EndWriteTagHelperAttributeMethodName { get; set; } = "EndWriteTagHelperAttribute";
public string MarkAsHtmlEncodedMethodName { get; set; } = "Html.Raw";
public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment";
public string WriteTagHelperOutputMethod { get; set; } = "Write";
public void WriteTagHelperBody(CodeRenderingContext context, DefaultTagHelperBodyIntermediateNode node)
{
if (DesignTime)
{
context.RenderChildren(node);
}
else
{
// Call into the tag helper scope manager to start a new tag helper scope.
// Also capture the value as the current execution context.
context.CodeWriter
.WriteStartAssignment(ExecutionContextVariableName)
.WriteStartInstanceMethodInvocation(
ScopeManagerVariableName,
ScopeManagerBeginMethodName);
// Assign a unique ID for this instance of the source HTML tag. This must be unique
// per call site, e.g. if the tag is on the view twice, there should be two IDs.
var uniqueId = (string)context.Items[CodeRenderingContext.SuppressUniqueIds];
if (uniqueId == null)
{
uniqueId = Guid.NewGuid().ToString("N");
}
context.CodeWriter.WriteStringLiteral(context.TagHelperRenderingContext.TagName)
.WriteParameterSeparator()
.Write(TagModeTypeName)
.Write(".")
.Write(context.TagHelperRenderingContext.TagMode.ToString())
.WriteParameterSeparator()
.WriteStringLiteral(uniqueId)
.WriteParameterSeparator();
// We remove and redirect writers so TagHelper authors can retrieve content.
using (context.Push(new RuntimeNodeWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
using (context.CodeWriter.BuildAsyncLambda())
{
context.RenderChildren(node);
}
}
context.CodeWriter.WriteEndMethodInvocation();
}
}
public void WriteTagHelperCreate(CodeRenderingContext context, DefaultTagHelperCreateIntermediateNode node)
{
context.CodeWriter
.WriteStartAssignment(node.Field)
.Write(CreateTagHelperMethodName)
.WriteLine("<global::" + node.Type + ">();");
if (!DesignTime)
{
context.CodeWriter.WriteInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddMethodName,
node.Field);
}
}
public void WriteTagHelperExecute(CodeRenderingContext context, DefaultTagHelperExecuteIntermediateNode node)
{
if (!DesignTime)
{
context.CodeWriter
.Write("await ")
.WriteStartInstanceMethodInvocation(
RunnerVariableName,
RunnerRunAsyncMethodName)
.Write(ExecutionContextVariableName)
.WriteEndMethodInvocation();
var tagHelperOutputAccessor = $"{ExecutionContextVariableName}.{ExecutionContextOutputPropertyName}";
context.CodeWriter
.Write("if (!")
.Write(tagHelperOutputAccessor)
.Write(".")
.Write(TagHelperOutputIsContentModifiedPropertyName)
.WriteLine(")");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.Write("await ")
.WriteInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextSetOutputContentAsyncMethodName);
}
context.CodeWriter
.WriteStartMethodInvocation(WriteTagHelperOutputMethod)
.Write(tagHelperOutputAccessor)
.WriteEndMethodInvocation()
.WriteStartAssignment(ExecutionContextVariableName)
.WriteInstanceMethodInvocation(
ScopeManagerVariableName,
ScopeManagerEndMethodName);
}
}
public void WriteTagHelperHtmlAttribute(CodeRenderingContext context, DefaultTagHelperHtmlAttributeIntermediateNode node)
{
if (DesignTime)
{
context.RenderChildren(node);
}
else
{
var attributeValueStyleParameter = $"{HtmlAttributeValueStyleTypeName}.{node.AttributeStructure}";
var isConditionalAttributeValue = node.Children.Any(
child => child is CSharpExpressionAttributeValueIntermediateNode || child is CSharpCodeAttributeValueIntermediateNode);
// All simple text and minimized attributes will be pre-allocated.
if (isConditionalAttributeValue)
{
// Dynamic attribute value should be run through the conditional attribute removal system. It's
// unbound and contains C#.
// TagHelper attribute rendering is buffered by default. We do not want to write to the current
// writer.
var valuePieceCount = node.Children.Count(
child =>
child is HtmlAttributeValueIntermediateNode ||
child is CSharpExpressionAttributeValueIntermediateNode ||
child is CSharpCodeAttributeValueIntermediateNode ||
child is ExtensionIntermediateNode);
context.CodeWriter
.WriteStartMethodInvocation(BeginAddHtmlAttributeValuesMethodName)
.Write(ExecutionContextVariableName)
.WriteParameterSeparator()
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(attributeValueStyleParameter)
.WriteEndMethodInvocation();
using (context.Push(new TagHelperHtmlAttributeRuntimeNodeWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteMethodInvocation(
EndAddHtmlAttributeValuesMethodName,
ExecutionContextVariableName);
}
else
{
// This is a data-* attribute which includes C#. Do not perform the conditional attribute removal or
// other special cases used when IsDynamicAttributeValue(). But the attribute must still be buffered to
// determine its final value.
// Attribute value is not plain text, must be buffered to determine its final value.
context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);
// We're building a writing scope around the provided chunks which captures everything written from the
// page. Therefore, we do not want to write to any other buffer since we're using the pages buffer to
// ensure we capture all content that's written, directly or indirectly.
using (context.Push(new RuntimeNodeWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteStartAssignment(StringValueBufferVariableName)
.WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
.WriteStartInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddHtmlAttributeMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStartMethodInvocation(MarkAsHtmlEncodedMethodName)
.Write(StringValueBufferVariableName)
.WriteEndMethodInvocation(endLine: false)
.WriteParameterSeparator()
.Write(attributeValueStyleParameter)
.WriteEndMethodInvocation();
}
}
}
public void WriteTagHelperProperty(CodeRenderingContext context, DefaultTagHelperPropertyIntermediateNode node)
{
var tagHelperRenderingContext = context.TagHelperRenderingContext;
var propertyName = node.BoundAttribute.GetPropertyName();
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, node.Field, node.AttributeName, node.BoundAttribute);
if (!DesignTime)
{
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelper.GetTypeName()}.{propertyName}"))
{
// Throw a reasonable Exception at runtime if the dictionary property is null.
context.CodeWriter
.Write("if (")
.Write(node.Field)
.Write(".")
.Write(propertyName)
.WriteLine(" == null)");
using (context.CodeWriter.BuildScope())
{
// System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName
// of InvalidOperationException type.
context.CodeWriter
.Write("throw ")
.WriteStartNewObject(nameof(InvalidOperationException))
.WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStringLiteral(node.TagHelper.GetTypeName())
.WriteParameterSeparator()
.WriteStringLiteral(propertyName)
.WriteEndMethodInvocation(endLine: false) // End of method call
.WriteEndMethodInvocation(); // End of new expression / throw statement
}
}
}
if (tagHelperRenderingContext.RenderedBoundAttributes.TryGetValue(node.AttributeName, out var previousValueAccessor))
{
context.CodeWriter
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.BoundAttribute.IsStringProperty || (node.IsIndexerNameMatch && node.BoundAttribute.IsIndexerStringProperty))
{
if (DesignTime)
{
context.RenderChildren(node);
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
if (node.Children.Count == 1 && node.Children.First() is HtmlContentIntermediateNode htmlNode)
{
var content = GetContent(htmlNode);
context.CodeWriter.WriteStringLiteral(content);
}
else
{
context.CodeWriter.Write("string.Empty");
}
context.CodeWriter.WriteLine(";");
}
else
{
context.CodeWriter.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);
using (context.Push(new LiteralRuntimeNodeWriter()))
{
context.RenderChildren(node);
}
context.CodeWriter
.WriteStartAssignment(StringValueBufferVariableName)
.WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
.WriteStartAssignment(propertyValueAccessor)
.Write(StringValueBufferVariableName)
.WriteLine(";");
}
}
else
{
if (DesignTime)
{
var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as IntermediateNode;
var valueStart = firstMappedChild?.Source;
using (context.CodeWriter.BuildLinePragma(node.Source))
{
var assignmentPrefixLength = propertyValueAccessor.Length + " = ".Length;
if (node.BoundAttribute.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is IntermediateToken token &&
token.IsCSharp)
{
assignmentPrefixLength += $"global::{node.BoundAttribute.TypeName}.".Length;
if (valueStart != null)
{
context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source, context);
}
context.CodeWriter
.WriteStartAssignment(propertyValueAccessor)
.Write("global::")
.Write(node.BoundAttribute.TypeName)
.Write(".");
}
else
{
if (valueStart != null)
{
context.CodeWriter.WritePadding(assignmentPrefixLength, node.Source, context);
}
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
}
RenderTagHelperAttributeInline(context, node, node.Source);
context.CodeWriter.WriteLine(";");
}
}
else
{
using (context.CodeWriter.BuildLinePragma(node.Source))
{
context.CodeWriter.WriteStartAssignment(propertyValueAccessor);
if (node.BoundAttribute.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is IntermediateToken token &&
token.IsCSharp)
{
context.CodeWriter
.Write("global::")
.Write(node.BoundAttribute.TypeName)
.Write(".");
}
RenderTagHelperAttributeInline(context, node, node.Source);
context.CodeWriter.WriteLine(";");
}
}
}
if (!DesignTime)
{
// We need to inform the context of the attribute value.
context.CodeWriter
.WriteStartInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddTagHelperAttributeMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.Write(propertyValueAccessor)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.AttributeStructure}")
.WriteEndMethodInvocation();
}
}
public void WriteTagHelperRuntime(CodeRenderingContext context, DefaultTagHelperRuntimeIntermediateNode node)
{
if (!DesignTime)
{
context.CodeWriter.WriteLine("#line hidden");
// Need to disable the warning "X is assigned to but never used." for the value buffer since
// whether it's used depends on how a TagHelper is used.
context.CodeWriter.WriteLine("#pragma warning disable 0414");
context.CodeWriter.WriteField(PrivateModifiers, "string", StringValueBufferVariableName);
context.CodeWriter.WriteLine("#pragma warning restore 0414");
context.CodeWriter.WriteField(PrivateModifiers, ExecutionContextTypeName, ExecutionContextVariableName);
context.CodeWriter
.Write("private ")
.Write(TagHelperRunnerTypeName)
.Write(" ")
.Write(RunnerVariableName)
.Write(" = new ")
.Write(TagHelperRunnerTypeName)
.WriteLine("();");
var backedScopeManageVariableName = "__backed" + ScopeManagerVariableName;
context.CodeWriter
.Write("private ")
.WriteVariableDeclaration(
ScopeManagerTypeName,
backedScopeManageVariableName,
value: null);
context.CodeWriter
.Write("private ")
.Write(ScopeManagerTypeName)
.Write(" ")
.WriteLine(ScopeManagerVariableName);
using (context.CodeWriter.BuildScope())
{
context.CodeWriter.WriteLine("get");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.Write("if (")
.Write(backedScopeManageVariableName)
.WriteLine(" == null)");
using (context.CodeWriter.BuildScope())
{
context.CodeWriter
.WriteStartAssignment(backedScopeManageVariableName)
.WriteStartNewObject(ScopeManagerTypeName)
.Write(StartTagHelperWritingScopeMethodName)
.WriteParameterSeparator()
.Write(EndTagHelperWritingScopeMethodName)
.WriteEndMethodInvocation();
}
context.CodeWriter
.Write("return ")
.Write(backedScopeManageVariableName)
.WriteLine(";");
}
}
}
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
DefaultTagHelperPropertyIntermediateNode property,
SourceSpan? span)
{
for (var i = 0; i < property.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, property.Children[i], span);
}
}
private void RenderTagHelperAttributeInline(
CodeRenderingContext context,
DefaultTagHelperPropertyIntermediateNode property,
IntermediateNode node,
SourceSpan? span)
{
if (node is CSharpExpressionIntermediateNode || node is HtmlContentIntermediateNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, property, node.Children[i], span);
}
}
else if (node is IntermediateToken token)
{
if (DesignTime && node.Source != null)
{
context.AddLineMappingFor(node);
}
context.CodeWriter.Write(token.Content);
}
else if (node is CSharpCodeIntermediateNode)
{
var error = new RazorError(
LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes,
SourceLocation.FromSpan(span),
span == null ? -1 : span.Value.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
else if (node is TemplateIntermediateNode)
{
var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(expectedTypeName),
SourceLocation.FromSpan(span),
span == null ? -1 : span.Value.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
}
private string GetContent(HtmlContentIntermediateNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is IntermediateToken token && token.IsHtml)
{
builder.Append(token.Content);
}
}
return builder.ToString();
}
private static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,
string attributeName,
BoundAttributeDescriptor descriptor)
{
var propertyAccessor = $"{tagHelperVariableName}.{descriptor.GetPropertyName()}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
}
}

View File

@ -0,0 +1,22 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public interface IDefaultTagHelperTargetExtension : ICodeTargetExtension
{
void WriteTagHelperBody(CodeRenderingContext context, DefaultTagHelperBodyIntermediateNode node);
void WriteTagHelperCreate(CodeRenderingContext context, DefaultTagHelperCreateIntermediateNode node);
void WriteTagHelperExecute(CodeRenderingContext context, DefaultTagHelperExecuteIntermediateNode node);
void WriteTagHelperHtmlAttribute(CodeRenderingContext context, DefaultTagHelperHtmlAttributeIntermediateNode node);
void WriteTagHelperProperty(CodeRenderingContext context, DefaultTagHelperPropertyIntermediateNode node);
void WriteTagHelperRuntime(CodeRenderingContext context, DefaultTagHelperRuntimeIntermediateNode node);
}
}

View File

@ -2,18 +2,17 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Extensions;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal interface IPreallocatedAttributeTargetExtension : ICodeTargetExtension
{
void WriteDeclarePreallocatedTagHelperHtmlAttribute(CodeRenderingContext context, DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode node);
void WriteTagHelperHtmlAttribute(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeIntermediateNode node);
void WriteAddPreallocatedTagHelperHtmlAttribute(CodeRenderingContext context, AddPreallocatedTagHelperHtmlAttributeIntermediateNode node);
void WriteTagHelperHtmlAttributeValue(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeValueIntermediateNode node);
void WriteDeclarePreallocatedTagHelperAttribute(CodeRenderingContext context, DeclarePreallocatedTagHelperAttributeIntermediateNode node);
void WriteTagHelperProperty(CodeRenderingContext context, PreallocatedTagHelperPropertyIntermediateNode node);
void WriteSetPreallocatedTagHelperProperty(CodeRenderingContext context, SetPreallocatedTagHelperPropertyIntermediateNode node);
void WriteTagHelperPropertyValue(CodeRenderingContext context, PreallocatedTagHelperPropertyValueIntermediateNode node);
}
}

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment";
public void WriteDeclarePreallocatedTagHelperHtmlAttribute(CodeRenderingContext context, DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode node)
public void WriteTagHelperHtmlAttributeValue(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeValueIntermediateNode node)
{
context.CodeWriter
.Write("private static readonly global::")
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + TagHelperAttributeTypeName)
.WriteStringLiteral(node.Name);
.WriteStringLiteral(node.AttributeName);
if (node.AttributeStructure == AttributeStructure.Minimized)
{
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
}
}
public void WriteAddPreallocatedTagHelperHtmlAttribute(CodeRenderingContext context, AddPreallocatedTagHelperHtmlAttributeIntermediateNode node)
public void WriteTagHelperHtmlAttribute(CodeRenderingContext context, PreallocatedTagHelperHtmlAttributeIntermediateNode node)
{
context.CodeWriter
.WriteStartInstanceMethodInvocation(ExecutionContextVariableName, ExecutionContextAddHtmlAttributeMethodName)
@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.WriteEndMethodInvocation();
}
public void WriteDeclarePreallocatedTagHelperAttribute(CodeRenderingContext context, DeclarePreallocatedTagHelperAttributeIntermediateNode node)
public void WriteTagHelperPropertyValue(CodeRenderingContext context, PreallocatedTagHelperPropertyValueIntermediateNode node)
{
context.CodeWriter
.Write("private static readonly global::")
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + TagHelperAttributeTypeName)
.WriteStringLiteral(node.Name)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStringLiteral(node.Value)
.WriteParameterSeparator()
@ -73,21 +73,20 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.WriteEndMethodInvocation();
}
public void WriteSetPreallocatedTagHelperProperty(CodeRenderingContext context, SetPreallocatedTagHelperPropertyIntermediateNode node)
public void WriteTagHelperProperty(CodeRenderingContext context, PreallocatedTagHelperPropertyIntermediateNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var propertyName = node.Descriptor.GetPropertyName();
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
var propertyName = node.BoundAttribute.GetPropertyName();
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, node.Field, node.AttributeName, node.BoundAttribute);
var attributeValueAccessor = $"{node.VariableName}.Value" /* ORIGINAL: TagHelperAttributeValuePropertyName */;
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
context.TagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelperTypeName}.{propertyName}"))
context.TagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelper.GetTypeName()}.{propertyName}"))
{
// Throw a reasonable Exception at runtime if the dictionary property is null.
context.CodeWriter
.Write("if (")
.Write(tagHelperVariableName)
.Write(node.Field)
.Write(".")
.Write(propertyName)
.WriteLine(" == null)");
@ -101,7 +100,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.WriteStringLiteral(node.TagHelperTypeName)
.WriteStringLiteral(node.TagHelper.GetTypeName())
.WriteParameterSeparator()
.WriteStringLiteral(propertyName)
.WriteEndMethodInvocation(endLine: false) // End of method call
@ -119,8 +118,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
.WriteEndMethodInvocation();
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
private static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,

View File

@ -10,7 +10,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal class PreallocatedTagHelperAttributeOptimizationPass : IntermediateNodePassBase, IRazorOptimizationPass
{
public override int Order => DefaultFeatureOrder;
// We want to run after the passes that 'lower' tag helpers.
public override int Order => DefaultFeatureOrder + 1000;
protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
{
@ -18,7 +19,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
walker.VisitDocument(documentNode);
}
internal class PreallocatedTagHelperWalker : IntermediateNodeWalker
internal class PreallocatedTagHelperWalker :
IntermediateNodeWalker,
IExtensionIntermediateNodeVisitor<DefaultTagHelperHtmlAttributeIntermediateNode>,
IExtensionIntermediateNodeVisitor<DefaultTagHelperPropertyIntermediateNode>
{
private const string PreAllocatedAttributeVariablePrefix = "__tagHelperAttribute_";
@ -34,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
VisitDefault(node);
}
public override void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIntermediateNode node)
public void VisitExtension(DefaultTagHelperHtmlAttributeIntermediateNode node)
{
if (node.Children.Count != 1 || !(node.Children.First() is HtmlContentIntermediateNode))
{
@ -44,15 +48,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var htmlContentNode = node.Children.First() as HtmlContentIntermediateNode;
var plainTextValue = GetContent(htmlContentNode);
DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode declaration = null;
PreallocatedTagHelperHtmlAttributeValueIntermediateNode declaration = null;
for (var i = 0; i < _classDeclaration.Children.Count; i++)
{
var current = _classDeclaration.Children[i];
if (current is DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode existingDeclaration)
if (current is PreallocatedTagHelperHtmlAttributeValueIntermediateNode existingDeclaration)
{
if (string.Equals(existingDeclaration.Name, node.Name, StringComparison.Ordinal) &&
if (string.Equals(existingDeclaration.AttributeName, node.AttributeName, StringComparison.Ordinal) &&
string.Equals(existingDeclaration.Value, plainTextValue, StringComparison.Ordinal) &&
existingDeclaration.AttributeStructure == node.AttributeStructure)
{
@ -66,17 +70,17 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
var variableCount = _classDeclaration.Children.Count - _variableCountOffset;
var preAllocatedAttributeVariableName = PreAllocatedAttributeVariablePrefix + variableCount;
declaration = new DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode
declaration = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode
{
VariableName = preAllocatedAttributeVariableName,
Name = node.Name,
AttributeName = node.AttributeName,
Value = plainTextValue,
AttributeStructure = node.AttributeStructure,
};
_classDeclaration.Children.Insert(_preallocatedDeclarationCount++, declaration);
}
var addPreAllocatedAttribute = new AddPreallocatedTagHelperHtmlAttributeIntermediateNode
var addPreAllocatedAttribute = new PreallocatedTagHelperHtmlAttributeIntermediateNode
{
VariableName = declaration.VariableName,
};
@ -85,9 +89,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
Parent.Children[nodeIndex] = addPreAllocatedAttribute;
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIntermediateNode node)
public void VisitExtension(DefaultTagHelperPropertyIntermediateNode node)
{
if (!(node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty)) ||
if (!(node.BoundAttribute.IsStringProperty || (node.IsIndexerNameMatch && node.BoundAttribute.IsIndexerStringProperty)) ||
node.Children.Count != 1 ||
!(node.Children.First() is HtmlContentIntermediateNode))
{
@ -97,15 +101,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var htmlContentNode = node.Children.First() as HtmlContentIntermediateNode;
var plainTextValue = GetContent(htmlContentNode);
DeclarePreallocatedTagHelperAttributeIntermediateNode declaration = null;
PreallocatedTagHelperPropertyValueIntermediateNode declaration = null;
for (var i = 0; i < _classDeclaration.Children.Count; i++)
{
var current = _classDeclaration.Children[i];
if (current is DeclarePreallocatedTagHelperAttributeIntermediateNode existingDeclaration)
if (current is PreallocatedTagHelperPropertyValueIntermediateNode existingDeclaration)
{
if (string.Equals(existingDeclaration.Name, node.AttributeName, StringComparison.Ordinal) &&
if (string.Equals(existingDeclaration.AttributeName, node.AttributeName, StringComparison.Ordinal) &&
string.Equals(existingDeclaration.Value, plainTextValue, StringComparison.Ordinal) &&
existingDeclaration.AttributeStructure == node.AttributeStructure)
{
@ -119,25 +123,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
var variableCount = _classDeclaration.Children.Count - _variableCountOffset;
var preAllocatedAttributeVariableName = PreAllocatedAttributeVariablePrefix + variableCount;
declaration = new DeclarePreallocatedTagHelperAttributeIntermediateNode
declaration = new PreallocatedTagHelperPropertyValueIntermediateNode()
{
VariableName = preAllocatedAttributeVariableName,
Name = node.AttributeName,
AttributeName = node.AttributeName,
Value = plainTextValue,
AttributeStructure = node.AttributeStructure,
};
_classDeclaration.Children.Insert(_preallocatedDeclarationCount++, declaration);
}
var setPreallocatedProperty = new SetPreallocatedTagHelperPropertyIntermediateNode
var setPreallocatedProperty = new PreallocatedTagHelperPropertyIntermediateNode(node)
{
VariableName = declaration.VariableName,
AttributeName = node.AttributeName,
TagHelperTypeName = node.TagHelperTypeName,
PropertyName = node.PropertyName,
Descriptor = node.Descriptor,
Binding = node.Binding,
IsIndexerNameMatch = node.IsIndexerNameMatch,
};
var nodeIndex = Parent.Children.IndexOf(node);

View File

@ -7,10 +7,10 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class AddPreallocatedTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode
internal sealed class PreallocatedTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode
{
public override RazorDiagnosticCollection Diagnostics { get; } = ReadOnlyDiagnosticCollection.Instance;
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override bool HasDiagnostics => false;
@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<AddPreallocatedTagHelperHtmlAttributeIntermediateNode>(this, visitor);
AcceptExtensionNode<PreallocatedTagHelperHtmlAttributeIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
return;
}
extension.WriteAddPreallocatedTagHelperHtmlAttribute(context, this);
extension.WriteTagHelperHtmlAttribute(context, this);
}
}
}

View File

@ -7,17 +7,41 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode : ExtensionIntermediateNode
internal sealed class PreallocatedTagHelperHtmlAttributeValueIntermediateNode : ExtensionIntermediateNode
{
public PreallocatedTagHelperHtmlAttributeValueIntermediateNode()
{
}
public PreallocatedTagHelperHtmlAttributeValueIntermediateNode(DefaultTagHelperHtmlAttributeIntermediateNode htmlAttributeNode)
{
if (htmlAttributeNode == null)
{
throw new ArgumentNullException(nameof(htmlAttributeNode));
}
Source = htmlAttributeNode.Source;
for (var i = 0; i < htmlAttributeNode.Children.Count; i++)
{
Children.Add(htmlAttributeNode.Children[i]);
}
for (var i = 0; i < htmlAttributeNode.Diagnostics.Count; i++)
{
Diagnostics.Add(htmlAttributeNode.Diagnostics[i]);
}
}
public override RazorDiagnosticCollection Diagnostics { get; } = ReadOnlyDiagnosticCollection.Instance;
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override bool HasDiagnostics => false;
public string VariableName { get; set; }
public string Name { get; set; }
public string AttributeName { get; set; }
public string Value { get; set; }
@ -30,7 +54,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode>(this, visitor);
AcceptExtensionNode<PreallocatedTagHelperHtmlAttributeValueIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
@ -52,7 +76,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
return;
}
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, this);
extension.WriteTagHelperHtmlAttributeValue(context, this);
}
}
}

View File

@ -7,28 +7,51 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class SetPreallocatedTagHelperPropertyIntermediateNode : ExtensionIntermediateNode
internal sealed class PreallocatedTagHelperPropertyIntermediateNode : ExtensionIntermediateNode
{
public PreallocatedTagHelperPropertyIntermediateNode()
{
}
public PreallocatedTagHelperPropertyIntermediateNode(DefaultTagHelperPropertyIntermediateNode propertyNode)
{
if (propertyNode == null)
{
throw new ArgumentNullException(nameof(propertyNode));
}
AttributeName = propertyNode.AttributeName;
AttributeStructure = propertyNode.AttributeStructure;
BoundAttribute = propertyNode.BoundAttribute;
Field = propertyNode.Field;
IsIndexerNameMatch = propertyNode.IsIndexerNameMatch;
Property = propertyNode.Property;
Source = propertyNode.Source;
TagHelper = propertyNode.TagHelper;
}
public override RazorDiagnosticCollection Diagnostics => ReadOnlyDiagnosticCollection.Instance;
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override bool HasDiagnostics => false;
public string VariableName { get; set; }
public string AttributeName { get; set; }
public string TagHelperTypeName { get; set; }
public AttributeStructure AttributeStructure { get; set; }
public string PropertyName { get; set; }
public BoundAttributeDescriptor BoundAttribute { get; set; }
public BoundAttributeDescriptor Descriptor { get; set; }
public TagHelperBinding Binding { get; set; }
public string Field { get; set; }
public bool IsIndexerNameMatch { get; set; }
public string Property { get; set; }
public TagHelperDescriptor TagHelper { get; set; }
public string VariableName { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
@ -36,7 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<SetPreallocatedTagHelperPropertyIntermediateNode>(this, visitor);
AcceptExtensionNode<PreallocatedTagHelperPropertyIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
@ -58,7 +81,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
return;
}
extension.WriteSetPreallocatedTagHelperProperty(context, this);
extension.WriteTagHelperProperty(context, this);
}
}
}

View File

@ -7,17 +7,17 @@ using Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
internal sealed class DeclarePreallocatedTagHelperAttributeIntermediateNode : ExtensionIntermediateNode
internal sealed class PreallocatedTagHelperPropertyValueIntermediateNode : ExtensionIntermediateNode
{
public override RazorDiagnosticCollection Diagnostics { get; } = ReadOnlyDiagnosticCollection.Instance;
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override bool HasDiagnostics => false;
public string VariableName { get; set; }
public string Name { get; set; }
public string AttributeName { get; set; }
public string Value { get; set; }
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DeclarePreallocatedTagHelperAttributeIntermediateNode>(this, visitor);
AcceptExtensionNode<PreallocatedTagHelperPropertyValueIntermediateNode>(this, visitor);
}
public override void WriteNode(CodeTarget target, CodeRenderingContext context)
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
return;
}
extension.WriteDeclarePreallocatedTagHelperAttribute(context, this);
extension.WriteTagHelperPropertyValue(context, this);
}
}
}

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
public sealed class TemplateIntermediateNode : ExtensionIntermediateNode
{
public override IntermediateNodeCollection Children { get; } = new DefaultIntermediateNodeCollection();
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)

View File

@ -3,7 +3,7 @@
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
internal static class CommonAnnotations
public static class CommonAnnotations
{
public static readonly object Imported = "Imported";
@ -12,5 +12,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public static readonly object PrimaryMethod = "PrimaryMethod";
public static readonly object PrimaryNamespace = "PrimaryNamespace";
public static class DefaultTagHelperExtension
{
public static readonly object TagHelperField = "TagHelperField";
}
}
}

View File

@ -1,59 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public sealed class CreateTagHelperIntermediateNode : IntermediateNode
{
private RazorDiagnosticCollection _diagnostics;
private ItemCollection _annotations;
public override ItemCollection Annotations
{
get
{
if (_annotations == null)
{
_annotations = new DefaultItemCollection();
}
return _annotations;
}
}
public override RazorDiagnosticCollection Diagnostics
{
get
{
if (_diagnostics == null)
{
_diagnostics = new DefaultRazorDiagnosticCollection();
}
return _diagnostics;
}
}
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override SourceSpan? Source { get; set; }
public override bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0;
public string TagHelperTypeName { get; set; }
public TagHelperDescriptor Descriptor { get; set; }
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
visitor.VisitCreateTagHelper(this);
}
}
}

View File

@ -1,58 +0,0 @@
// 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;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public sealed class DeclareTagHelperFieldsIntermediateNode : IntermediateNode
{
private RazorDiagnosticCollection _diagnostics;
private ItemCollection _annotations;
public override ItemCollection Annotations
{
get
{
if (_annotations == null)
{
_annotations = new DefaultItemCollection();
}
return _annotations;
}
}
public override RazorDiagnosticCollection Diagnostics
{
get
{
if (_diagnostics == null)
{
_diagnostics = new DefaultRazorDiagnosticCollection();
}
return _diagnostics;
}
}
public override IntermediateNodeCollection Children => ReadOnlyIntermediateNodeCollection.Instance;
public override SourceSpan? Source { get; set; }
public override bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0;
public ISet<string> UsedTagHelperTypeNames { get; set; } = new HashSet<string>(StringComparer.Ordinal);
public override void Accept(IntermediateNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
visitor.VisitDeclareTagHelperFields(this);
}
}
}

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0;
public string Name { get; set; }
public string AttributeName { get; set; }
public string Prefix { get; set; }

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{

View File

@ -42,5 +42,35 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
}
}
}
public static IReadOnlyList<TNode> FindDescendantNodes<TNode>(this IntermediateNode node)
where TNode : IntermediateNode
{
var visitor = new Visitor<TNode>();
visitor.Visit(node);
if (visitor.Results.Count > 0 && visitor.Results[0] == node)
{
// Don't put the node itself in the results
visitor.Results.Remove((TNode)node);
}
return visitor.Results;
}
private class Visitor<TNode> : IntermediateNodeWalker where TNode : IntermediateNode
{
public List<TNode> Results { get; } = new List<TNode>();
public override void VisitDefault(IntermediateNode node)
{
if (node is TNode match)
{
Results.Add(match);
}
base.VisitDefault(node);
}
}
}
}

View File

@ -109,11 +109,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
VisitDefault(node);
}
public virtual void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIntermediateNode node)
{
VisitDefault(node);
}
public virtual void VisitTagHelper(TagHelperIntermediateNode node)
{
VisitDefault(node);
@ -124,17 +119,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
VisitDefault(node);
}
public virtual void VisitCreateTagHelper(CreateTagHelperIntermediateNode node)
public virtual void VisitTagHelperProperty(TagHelperPropertyIntermediateNode node)
{
VisitDefault(node);
}
public virtual void VisitSetTagHelperProperty(SetTagHelperPropertyIntermediateNode node)
{
VisitDefault(node);
}
public virtual void VisitAddTagHelperHtmlAttribute(AddTagHelperHtmlAttributeIntermediateNode node)
public virtual void VisitTagHelperHtmlAttribute(TagHelperHtmlAttributeIntermediateNode node)
{
VisitDefault(node);
}

View File

@ -5,7 +5,7 @@ using System;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public sealed class AddTagHelperHtmlAttributeIntermediateNode : IntermediateNode
public sealed class TagHelperHtmlAttributeIntermediateNode : IntermediateNode
{
private RazorDiagnosticCollection _diagnostics;
private ItemCollection _annotations;
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0;
public string Name { get; set; }
public string AttributeName { get; set; }
public AttributeStructure AttributeStructure { get; set; }
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
throw new ArgumentNullException(nameof(visitor));
}
visitor.VisitAddTagHelperHtmlAttribute(this);
visitor.VisitTagHelperHtmlAttribute(this);
}
}
}

View File

@ -47,24 +47,24 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public string TagName { get; set; }
public TagMode TagMode { get; set; }
public ICollection<TagHelperDescriptor> TagHelpers { get; } = new List<TagHelperDescriptor>();
public TagHelperBodyIntermediateNode Body => Children.OfType<TagHelperBodyIntermediateNode>().SingleOrDefault();
public IEnumerable<SetTagHelperPropertyIntermediateNode> SetTagHelperProperties
public IEnumerable<TagHelperPropertyIntermediateNode> Properties
{
get
{
return Children.OfType<SetTagHelperPropertyIntermediateNode>();
return Children.OfType<TagHelperPropertyIntermediateNode>();
}
}
public IEnumerable<AddTagHelperHtmlAttributeIntermediateNode> AddTagHelperHtmlAttributes
public IEnumerable<TagHelperHtmlAttributeIntermediateNode> HtmlAttributes
{
get
{
return Children.OfType<AddTagHelperHtmlAttributeIntermediateNode>();
return Children.OfType<TagHelperHtmlAttributeIntermediateNode>();
}
}

View File

@ -5,7 +5,7 @@ using System;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public sealed class SetTagHelperPropertyIntermediateNode : IntermediateNode
public sealed class TagHelperPropertyIntermediateNode : IntermediateNode
{
private RazorDiagnosticCollection _diagnostics;
private ItemCollection _annotations;
@ -42,17 +42,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override bool HasDiagnostics => _diagnostics != null && _diagnostics.Count > 0;
public string TagHelperTypeName { get; set; }
public string PropertyName { get; set; }
public string AttributeName { get; set; }
public AttributeStructure AttributeStructure { get; set; }
public BoundAttributeDescriptor Descriptor { get; set; }
public BoundAttributeDescriptor BoundAttribute { get; set; }
public TagHelperBinding Binding { get; set; }
public TagHelperDescriptor TagHelper { get; set; }
public bool IsIndexerNameMatch { get; set; }
@ -63,7 +59,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
throw new ArgumentNullException(nameof(visitor));
}
visitor.VisitSetTagHelperProperty(this);
visitor.VisitTagHelperProperty(this);
}
}
}

View File

@ -14,6 +14,8 @@ namespace Microsoft.AspNetCore.Razor.Language
public abstract bool IsReadOnly { get; }
public abstract void Add(object key, object value);
public abstract void Add(KeyValuePair<object, object> item);
public abstract void Clear();

View File

@ -15,6 +15,11 @@ namespace Microsoft.AspNetCore.Razor.Language
return new DefaultRazorCodeGenerationOptions(indentWithTabs: false, indentSize: 4, designTime: false, suppressChecksum: false);
}
public static RazorCodeGenerationOptions CreateDesignTimeDefault()
{
return new DefaultRazorCodeGenerationOptions(indentWithTabs: false, indentSize: 4, designTime: true, suppressChecksum: false);
}
public abstract bool DesignTime { get; }
public abstract bool IndentWithTabs { get; }

View File

@ -66,6 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language
$"{DiagnosticPrefix}3000",
() => Resources.TagHelper_InvalidRestrictedChildNullOrWhitespace,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateTagHelper_InvalidRestrictedChildNullOrWhitespace(string tagHelperDisplayName)
{
var diagnostic = RazorDiagnostic.Create(

View File

@ -72,9 +72,10 @@ namespace Microsoft.AspNetCore.Razor.Language
// Intermediate Node Passes
builder.Features.Add(new DefaultDocumentClassifierPass());
builder.Features.Add(new DirectiveRemovalOptimizationPass());
builder.Features.Add(new DefaultTagHelperOptimizationPass());
// Default Runtime Targets
builder.AddTargetExtension(new PreallocatedAttributeTargetExtension());
// Default Code Target Extensions
// (currently none)
// Default configuration
var configurationFeature = new DefaultDocumentClassifierPassFeature();
@ -104,7 +105,12 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static void AddRuntimeDefaults(IRazorEngineBuilder builder)
{
// Intermediate Node Passes
builder.Features.Add(new PreallocatedTagHelperAttributeOptimizationPass());
// Code Target Extensions
builder.AddTargetExtension(new DefaultTagHelperTargetExtension() { DesignTime = false });
builder.AddTargetExtension(new PreallocatedAttributeTargetExtension());
}
internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder)
@ -115,7 +121,8 @@ namespace Microsoft.AspNetCore.Razor.Language
// Intermediate Node Passes
builder.Features.Add(new DesignTimeDirectivePass());
// DesignTime Runtime Targets
// Code Target Extensions
builder.AddTargetExtension(new DefaultTagHelperTargetExtension() { DesignTime = true });
builder.AddTargetExtension(new DesignTimeDirectiveTargetExtension());
}

View File

@ -21,6 +21,16 @@ namespace Microsoft.AspNetCore.Razor.Language
public override bool IsReadOnly => true;
public override void Add(object key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
throw new NotSupportedException();
}
public override void Add(KeyValuePair<object, object> item)
{
if (item.Key == null)

View File

@ -71,6 +71,20 @@ namespace Microsoft.AspNetCore.Razor.Language
/// <remarks>Set property is only accessible for deserialization purposes.</remarks>
public int CharacterIndex { get; set; }
/// <summary>
/// Creates a new instance of <see cref="SourceLocation"/> from the provided span.
/// </summary>
/// <param name="span">
/// The souce span. If <c>null</c>, <see cref="SourceLocation.Undefined"/> will be returned.
/// </param>
/// <remarks>A <see cref="SourceLocation"/> that corresponds to the beginning of the span.</remarks>
public static SourceLocation FromSpan(SourceSpan? span)
{
return span == null ?
SourceLocation.Undefined :
new SourceLocation(span.Value.FilePath, span.Value.AbsoluteIndex, span.Value.LineIndex, span.Value.CharacterIndex);
}
/// <inheritdoc />
public override string ToString()
{

View File

@ -3,8 +3,8 @@
namespace Microsoft.AspNetCore.Razor.Language
{
internal static class TagHelperConventions
public static class TagHelperConventions
{
internal const string DefaultKind = "ITagHelper";
public static readonly string DefaultKind = "ITagHelper";
}
}

View File

@ -7,16 +7,36 @@ namespace Microsoft.AspNetCore.Razor.Language
{
public static class TagHelperDescriptorExtensions
{
public static string GetTypeName(this TagHelperDescriptor descriptor)
public static string GetTypeName(this TagHelperDescriptor tagHelper)
{
descriptor.Metadata.TryGetValue(TagHelperMetadata.Common.TypeName, out var typeName);
if (tagHelper == null)
{
throw new ArgumentNullException(nameof(tagHelper));
}
tagHelper.Metadata.TryGetValue(TagHelperMetadata.Common.TypeName, out var typeName);
return typeName;
}
public static bool IsDefaultKind(this TagHelperDescriptor descriptor)
public static bool IsDefaultKind(this TagHelperDescriptor tagHelper)
{
return string.Equals(descriptor.Kind, TagHelperConventions.DefaultKind, StringComparison.Ordinal);
if (tagHelper == null)
{
throw new ArgumentNullException(nameof(tagHelper));
}
return string.Equals(tagHelper.Kind, TagHelperConventions.DefaultKind, StringComparison.Ordinal);
}
public static bool KindUsesDefaultTagHelperRuntime(this TagHelperDescriptor tagHelper)
{
if (tagHelper == null)
{
throw new ArgumentNullException(nameof(tagHelper));
}
tagHelper.Metadata.TryGetValue(TagHelperMetadata.Runtime.Name, out var value);
return string.Equals(TagHelperConventions.DefaultKind, value, StringComparison.Ordinal);
}
}
}

View File

@ -3,13 +3,18 @@
namespace Microsoft.AspNetCore.Razor.Language
{
internal static class TagHelperMetadata
public static class TagHelperMetadata
{
public static class Common
{
internal const string PropertyName = "Common.PropertyName";
public static readonly string PropertyName = "Common.PropertyName";
internal const string TypeName = "Common.TypeName";
public static readonly string TypeName = "Common.TypeName";
}
public static class Runtime
{
public static readonly string Name = "Runtime.Name";
}
}
}

View File

@ -57,6 +57,7 @@ namespace Microsoft.CodeAnalysis.Razor
var typeName = GetFullName(type);
var assemblyName = type.ContainingAssembly.Identity.Name;
var descriptorBuilder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
descriptorBuilder.SetTypeName(typeName);

View File

@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new TagHelperIntermediateNode());
builder.Push(new AddTagHelperHtmlAttributeIntermediateNode());
builder.Push(new TagHelperHtmlAttributeIntermediateNode());
builder.Push(new CSharpExpressionIntermediateNode()
{
@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
n,
c =>
{
Assert.IsType<AddTagHelperHtmlAttributeIntermediateNode>(c);
Assert.IsType<TagHelperHtmlAttributeIntermediateNode>(c);
Children(
c,
s => CSharpExpression("Hi", s));
@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var builder = IntermediateNodeBuilder.Create(document);
builder.Push(new TagHelperIntermediateNode());
builder.Push(new SetTagHelperPropertyIntermediateNode());
builder.Push(new TagHelperPropertyIntermediateNode());
builder.Push(new CSharpExpressionIntermediateNode()
{
@ -218,7 +218,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
n,
c =>
{
Assert.IsType<SetTagHelperPropertyIntermediateNode>(c);
Assert.IsType<TagHelperPropertyIntermediateNode>(c);
Children(
c,
s => CSharpExpression("Hi", s));

View File

@ -547,9 +547,10 @@ public class AllTagHelper : {typeof(TagHelper).FullName}
IEnumerable<MetadataReference> compilationReferences,
IEnumerable<string> expectedErrors = null)
{
var syntaxTree = CSharpSyntaxTree.ParseText(document.GetCSharpDocument().GeneratedCode);
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var cSharp = document.GetCSharpDocument().GeneratedCode;
var syntaxTree = CSharpSyntaxTree.ParseText(cSharp);
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var compilation = CSharpCompilation.Create("CodeGenerationTestAssembly", new[] { syntaxTree }, compilationReferences, options);
var diagnostics = compilation.GetDiagnostics();

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<SetTagHelperPropertyIntermediateNode>().Single();
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var token = Assert.IsType<IntermediateToken>(Assert.Single(setProperty.Children));
Assert.True(token.IsCSharp);
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<SetTagHelperPropertyIntermediateNode>().Single();
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var expression = Assert.IsType<CSharpExpressionIntermediateNode>(Assert.Single(setProperty.Children));
Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => __model.Bar)", GetCSharpContent(expression));
@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
// Assert
var tagHelper = FindTagHelperNode(irDocument);
var setProperty = tagHelper.Children.OfType<SetTagHelperPropertyIntermediateNode>().Single();
var setProperty = tagHelper.Children.OfType<TagHelperPropertyIntermediateNode>().Single();
var expression = Assert.IsType<CSharpExpressionIntermediateNode>(Assert.Single(setProperty.Children));
Assert.Equal("ModelExpressionProvider.CreateModelExpression(ViewData, __model => Bar)", GetCSharpContent(expression));

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
[Fact]
public void IsViewComponentKind_ReturnsFalse_ForNonVCTHDescriptor()
{
//Arrange
// Arrange
var tagHelper = CreateTagHelperDescriptor();
// Act
@ -62,21 +62,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
private static TagHelperDescriptor CreateTagHelperDescriptor()
{
var descriptor = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName")
var tagHelper = TagHelperDescriptorBuilder.Create("TypeName", "AssemblyName")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name"))
.Build();
return descriptor;
return tagHelper;
}
private static TagHelperDescriptor CreateViewComponentTagHelperDescriptor(string name = "ViewComponentName")
{
var descriptor = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName")
var tagHelper = TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TypeName", "AssemblyName")
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tag-name"))
.AddMetadata(ViewComponentTagHelperMetadata.Name, name)
.Build();
return descriptor;
return tagHelper;
}
}
}

View File

@ -14,6 +14,7 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime>
{
private global::InputTestTagHelper __InputTestTagHelper;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -27,7 +28,6 @@ global::System.Object __typeHelper = "InputTestTagHelper, AppCode";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::InputTestTagHelper __InputTestTagHelper = null;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -11,6 +11,8 @@ Document -
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime> -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
@ -29,31 +31,32 @@ Document -
DirectiveToken - (33:2,14 [29] ModelExpressionTagHelper.cshtml) - "InputTestTagHelper, AppCode"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - InputTestTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (17:1,0 [2] ModelExpressionTagHelper.cshtml)
IntermediateToken - (17:1,0 [2] ModelExpressionTagHelper.cshtml) - Html - \n
HtmlContent - (62:2,43 [4] ModelExpressionTagHelper.cshtml)
IntermediateToken - (62:2,43 [4] ModelExpressionTagHelper.cshtml) - Html - \n\n
TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - InputTestTagHelper
SetTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - For - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - InputTestTagHelper
DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model =>
IntermediateToken - - CSharp - __model.
IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date
IntermediateToken - - CSharp - )
DefaultTagHelperExecute -
HtmlContent - (91:4,25 [2] ModelExpressionTagHelper.cshtml)
IntermediateToken - (91:4,25 [2] ModelExpressionTagHelper.cshtml) - Html - \n
TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - InputTestTagHelper
SetTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - For - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - InputTestTagHelper
DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model =>
IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model
IntermediateToken - - CSharp - )
DefaultTagHelperExecute -
HtmlContent - (120:5,27 [2] ModelExpressionTagHelper.cshtml)
IntermediateToken - (120:5,27 [2] ModelExpressionTagHelper.cshtml) - Html - \n
Inject -

View File

@ -1,20 +1,20 @@
Source Location: (7:0,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml)
|DateTime|
Generated Location: (889:19,0 [8] )
Generated Location: (955:20,0 [8] )
|DateTime|
Source Location: (33:2,14 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml)
|"InputTestTagHelper, AppCode"|
Generated Location: (1030:23,37 [29] )
Generated Location: (1096:24,37 [29] )
|"InputTestTagHelper, AppCode"|
Source Location: (83:4,17 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml)
|Date|
Generated Location: (1675:35,102 [4] )
Generated Location: (1668:35,102 [4] )
|Date|
Source Location: (111:5,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ModelExpressionTagHelper.cshtml)
|Model|
Generated Location: (1991:41,94 [5] )
Generated Location: (1984:41,94 [5] )
|Model|

View File

@ -16,9 +16,9 @@ namespace AspNetCore
{
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -32,7 +32,7 @@ namespace AspNetCore
return __backed__tagHelperScopeManager;
}
}
private global::InputTestTagHelper __InputTestTagHelper = null;
private global::InputTestTagHelper __InputTestTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -10,7 +10,8 @@ Document -
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime> -
DeclareTagHelperFields - - InputTestTagHelper
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::InputTestTagHelper - __InputTestTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(17, 2, true);
@ -27,14 +28,15 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(66, 25, false);
TagHelper - (66:4,0 [25] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - InputTestTagHelper
SetTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - For - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - InputTestTagHelper
DefaultTagHelperProperty - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model =>
IntermediateToken - - CSharp - __model.
IntermediateToken - (83:4,17 [4] ModelExpressionTagHelper.cshtml) - CSharp - Date
IntermediateToken - - CSharp - )
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -46,13 +48,14 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(93, 27, false);
TagHelper - (93:5,0 [27] ModelExpressionTagHelper.cshtml) - input-test - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - InputTestTagHelper
SetTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - For - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - InputTestTagHelper
DefaultTagHelperProperty - (110:5,17 [6] ModelExpressionTagHelper.cshtml) - for - Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression InputTestTagHelper.For - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - ModelExpressionProvider.CreateModelExpression(ViewData, __model =>
IntermediateToken - (111:5,18 [5] ModelExpressionTagHelper.cshtml) - CSharp - Model
IntermediateToken - - CSharp - )
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -

View File

@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
#line hidden
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
private global::DivTagHelper __DivTagHelper;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -28,7 +29,6 @@ global::System.Object __typeHelper = "*, AppCode";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::DivTagHelper __DivTagHelper = null;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -12,6 +12,8 @@ Document -
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingDirective - (38:3,1 [41] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
@ -29,7 +31,6 @@ Document -
DirectiveToken - (23:2,14 [12] RazorPagesWithoutModel.cshtml) - "*, AppCode"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - DivTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (7:1,0 [2] RazorPagesWithoutModel.cshtml)
IntermediateToken - (7:1,0 [2] RazorPagesWithoutModel.cshtml) - Html - \n
@ -49,15 +50,16 @@ Document -
IntermediateToken - (449:21,43 [1] RazorPagesWithoutModel.cshtml) - Html - >
IntermediateToken - (450:21,44 [6] RazorPagesWithoutModel.cshtml) - Html - \n
TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (468:22,16 [11] RazorPagesWithoutModel.cshtml)
IntermediateToken - (468:22,16 [11] RazorPagesWithoutModel.cshtml) - Html - text-danger
DefaultTagHelperExecute -
HtmlContent - (487:22,35 [6] RazorPagesWithoutModel.cshtml)
IntermediateToken - (487:22,35 [6] RazorPagesWithoutModel.cshtml) - Html - \n
TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml)
IntermediateToken - (517:23,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n
IntermediateToken - (527:24,8 [6] RazorPagesWithoutModel.cshtml) - Html - <label
@ -69,7 +71,7 @@ Document -
IntermediateToken - (570:24,51 [8] RazorPagesWithoutModel.cshtml) - Html - </label>
IntermediateToken - (578:24,59 [10] RazorPagesWithoutModel.cshtml) - Html - \n
TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml)
IntermediateToken - (611:25,31 [14] RazorPagesWithoutModel.cshtml) - Html - \n
IntermediateToken - (625:26,12 [6] RazorPagesWithoutModel.cshtml) - Html - <input
@ -81,24 +83,26 @@ Document -
IntermediateToken - (694:27,37 [1] RazorPagesWithoutModel.cshtml) - Html - >
IntermediateToken - (695:27,38 [7] RazorPagesWithoutModel.cshtml) - Html - </span>
IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (600:25,20 [9] RazorPagesWithoutModel.cshtml)
IntermediateToken - (600:25,20 [9] RazorPagesWithoutModel.cshtml) - Html - col-md-10
DefaultTagHelperExecute -
HtmlContent - (718:28,14 [6] RazorPagesWithoutModel.cshtml)
IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (505:23,16 [10] RazorPagesWithoutModel.cshtml)
IntermediateToken - (505:23,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group
DefaultTagHelperExecute -
HtmlContent - (730:29,10 [6] RazorPagesWithoutModel.cshtml)
IntermediateToken - (730:29,10 [6] RazorPagesWithoutModel.cshtml) - Html - \n
TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml)
IntermediateToken - (760:30,28 [10] RazorPagesWithoutModel.cshtml) - Html - \n
TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml)
IntermediateToken - (809:31,47 [14] RazorPagesWithoutModel.cshtml) - Html - \n
IntermediateToken - (823:32,12 [7] RazorPagesWithoutModel.cshtml) - Html - <button
@ -108,16 +112,18 @@ Document -
IntermediateToken - (869:32,58 [4] RazorPagesWithoutModel.cshtml) - Html - Save
IntermediateToken - (873:32,62 [9] RazorPagesWithoutModel.cshtml) - Html - </button>
IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (782:31,20 [25] RazorPagesWithoutModel.cshtml)
IntermediateToken - (782:31,20 [25] RazorPagesWithoutModel.cshtml) - Html - col-md-offset-2 col-md-10
DefaultTagHelperExecute -
HtmlContent - (898:33,14 [6] RazorPagesWithoutModel.cshtml)
IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (748:30,16 [10] RazorPagesWithoutModel.cshtml)
IntermediateToken - (748:30,16 [10] RazorPagesWithoutModel.cshtml) - Html - form-group
DefaultTagHelperExecute -
HtmlContent - (910:34,10 [11] RazorPagesWithoutModel.cshtml)
IntermediateToken - (910:34,10 [2] RazorPagesWithoutModel.cshtml) - Html - \n
IntermediateToken - (912:35,0 [7] RazorPagesWithoutModel.cshtml) - Html - </form>

View File

@ -5,12 +5,12 @@ Generated Location: (696:15,0 [41] )
Source Location: (23:2,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml)
|"*, AppCode"|
Generated Location: (1099:24,37 [12] )
Generated Location: (1153:25,37 [12] )
|"*, AppCode"|
Source Location: (566:24,47 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml)
|Name|
Generated Location: (1647:36,47 [4] )
Generated Location: (1640:36,47 [4] )
|Name|
Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPagesWithoutModel.cshtml)
@ -28,7 +28,7 @@ Source Location: (95:5,12 [283] TestFiles/IntegrationTests/CodeGenerationIntegra
public string Name { get; set; }
}
|
Generated Location: (2128:47,12 [283] )
Generated Location: (2121:47,12 [283] )
|
public IActionResult OnPost(Customer customer)
{

View File

@ -25,9 +25,9 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("col-md-offset-2 col-md-10"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -41,7 +41,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
return __backed__tagHelperScopeManager;
}
}
private global::DivTagHelper __DivTagHelper = null;
private global::DivTagHelper __DivTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -11,11 +11,12 @@ Document -
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingDirective - (38:3,1 [43] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 - class - text-danger - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - class - col-md-10 - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - class - form-group - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - AttributeStructure.DoubleQuotes
DeclareTagHelperFields - - DivTagHelper
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(7, 2, true);
@ -47,9 +48,10 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(456, 31, false);
TagHelper - (456:22,4 [31] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperBody -
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -61,7 +63,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(493, 237, false);
TagHelper - (493:23,4 [237] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(517, 48, true);
HtmlContent - (517:23,28 [48] RazorPagesWithoutModel.cshtml)
@ -87,7 +89,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(588, 130, false);
TagHelper - (588:25,8 [130] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(611, 101, true);
HtmlContent - (611:25,31 [101] RazorPagesWithoutModel.cshtml)
@ -103,8 +105,9 @@ Document -
IntermediateToken - (702:27,45 [10] RazorPagesWithoutModel.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -113,8 +116,9 @@ Document -
IntermediateToken - (718:28,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -126,7 +130,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(736, 174, false);
TagHelper - (736:30,4 [174] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(760, 10, true);
HtmlContent - (760:30,28 [10] RazorPagesWithoutModel.cshtml)
@ -136,7 +140,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(770, 128, false);
TagHelper - (770:31,8 [128] RazorPagesWithoutModel.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(809, 83, true);
HtmlContent - (809:31,47 [83] RazorPagesWithoutModel.cshtml)
@ -150,8 +154,9 @@ Document -
IntermediateToken - (882:32,71 [10] RazorPagesWithoutModel.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -160,8 +165,9 @@ Document -
IntermediateToken - (898:33,14 [6] RazorPagesWithoutModel.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -

View File

@ -19,6 +19,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
#line hidden
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml : global::Microsoft.AspNetCore.Mvc.RazorPages.Page
{
private global::DivTagHelper __DivTagHelper;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -32,7 +33,6 @@ global::System.Object __typeHelper = "*, AppCode";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::DivTagHelper __DivTagHelper = null;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -12,6 +12,8 @@ Document -
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingDirective - (55:4,1 [41] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
@ -30,7 +32,6 @@ Document -
DirectiveToken - (40:3,14 [12] RazorPages.cshtml) - "*, AppCode"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - DivTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (7:1,0 [2] RazorPages.cshtml)
IntermediateToken - (7:1,0 [2] RazorPages.cshtml) - Html - \n
@ -50,15 +51,16 @@ Document -
IntermediateToken - (543:25,43 [2] RazorPages.cshtml) - Html - >
IntermediateToken - (545:25,45 [6] RazorPages.cshtml) - Html - \n
TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (563:26,16 [11] RazorPages.cshtml)
IntermediateToken - (563:26,16 [11] RazorPages.cshtml) - Html - text-danger
DefaultTagHelperExecute -
HtmlContent - (582:26,35 [6] RazorPages.cshtml)
IntermediateToken - (582:26,35 [6] RazorPages.cshtml) - Html - \n
TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (612:27,28 [48] RazorPages.cshtml)
IntermediateToken - (612:27,28 [10] RazorPages.cshtml) - Html - \n
IntermediateToken - (622:28,8 [6] RazorPages.cshtml) - Html - <label
@ -70,7 +72,7 @@ Document -
IntermediateToken - (671:28,57 [8] RazorPages.cshtml) - Html - </label>
IntermediateToken - (679:28,65 [10] RazorPages.cshtml) - Html - \n
TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (712:29,31 [101] RazorPages.cshtml)
IntermediateToken - (712:29,31 [14] RazorPages.cshtml) - Html - \n
IntermediateToken - (726:30,12 [6] RazorPages.cshtml) - Html - <input
@ -82,24 +84,26 @@ Document -
IntermediateToken - (795:31,37 [1] RazorPages.cshtml) - Html - >
IntermediateToken - (796:31,38 [7] RazorPages.cshtml) - Html - </span>
IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (701:29,20 [9] RazorPages.cshtml)
IntermediateToken - (701:29,20 [9] RazorPages.cshtml) - Html - col-md-10
DefaultTagHelperExecute -
HtmlContent - (819:32,14 [6] RazorPages.cshtml)
IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (600:27,16 [10] RazorPages.cshtml)
IntermediateToken - (600:27,16 [10] RazorPages.cshtml) - Html - form-group
DefaultTagHelperExecute -
HtmlContent - (831:33,10 [6] RazorPages.cshtml)
IntermediateToken - (831:33,10 [6] RazorPages.cshtml) - Html - \n
TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (861:34,28 [10] RazorPages.cshtml)
IntermediateToken - (861:34,28 [10] RazorPages.cshtml) - Html - \n
TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (910:35,47 [83] RazorPages.cshtml)
IntermediateToken - (910:35,47 [14] RazorPages.cshtml) - Html - \n
IntermediateToken - (924:36,12 [7] RazorPages.cshtml) - Html - <button
@ -109,16 +113,18 @@ Document -
IntermediateToken - (970:36,58 [4] RazorPages.cshtml) - Html - Save
IntermediateToken - (974:36,62 [9] RazorPages.cshtml) - Html - </button>
IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (883:35,20 [25] RazorPages.cshtml)
IntermediateToken - (883:35,20 [25] RazorPages.cshtml) - Html - col-md-offset-2 col-md-10
DefaultTagHelperExecute -
HtmlContent - (999:37,14 [6] RazorPages.cshtml)
IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n
CreateTagHelper - - DivTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - DivTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (849:34,16 [10] RazorPages.cshtml)
IntermediateToken - (849:34,16 [10] RazorPages.cshtml) - Html - form-group
DefaultTagHelperExecute -
HtmlContent - (1011:38,10 [11] RazorPages.cshtml)
IntermediateToken - (1011:38,10 [2] RazorPages.cshtml) - Html - \n
IntermediateToken - (1013:39,0 [7] RazorPages.cshtml) - Html - </form>

View File

@ -5,17 +5,17 @@ Generated Location: (672:15,0 [41] )
Source Location: (16:2,7 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml)
|NewModel|
Generated Location: (1026:24,0 [8] )
Generated Location: (1080:25,0 [8] )
|NewModel|
Source Location: (40:3,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml)
|"*, AppCode"|
Generated Location: (1167:28,37 [12] )
Generated Location: (1221:29,37 [12] )
|"*, AppCode"|
Source Location: (661:28,47 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml)
|Model.Name|
Generated Location: (1703:40,47 [10] )
Generated Location: (1696:40,47 [10] )
|Model.Name|
Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorPages.cshtml)
@ -36,7 +36,7 @@ Source Location: (112:6,12 [360] TestFiles/IntegrationTests/CodeGenerationIntegr
public string Name { get; set; }
}
|
Generated Location: (2178:51,12 [360] )
Generated Location: (2171:51,12 [360] )
|
public class NewModel : PageModel
{

View File

@ -25,9 +25,9 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("col-md-offset-2 col-md-10"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -41,7 +41,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
return __backed__tagHelperScopeManager;
}
}
private global::DivTagHelper __DivTagHelper = null;
private global::DivTagHelper __DivTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -11,11 +11,12 @@ Document -
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingDirective - (55:4,1 [43] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 - class - text-danger - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - class - col-md-10 - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - class - form-group - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - AttributeStructure.DoubleQuotes
DeclareTagHelperFields - - DivTagHelper
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - text-danger - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - col-md-10 - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - form-group - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - col-md-offset-2 col-md-10 - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(7, 2, true);
@ -47,9 +48,10 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(551, 31, false);
TagHelper - (551:26,4 [31] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperBody -
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -61,7 +63,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(588, 243, false);
TagHelper - (588:27,4 [243] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(612, 48, true);
HtmlContent - (612:27,28 [48] RazorPages.cshtml)
@ -87,7 +89,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(689, 130, false);
TagHelper - (689:29,8 [130] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(712, 101, true);
HtmlContent - (712:29,31 [101] RazorPages.cshtml)
@ -103,8 +105,9 @@ Document -
IntermediateToken - (803:31,45 [10] RazorPages.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -113,8 +116,9 @@ Document -
IntermediateToken - (819:32,14 [6] RazorPages.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -126,7 +130,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(837, 174, false);
TagHelper - (837:34,4 [174] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(861, 10, true);
HtmlContent - (861:34,28 [10] RazorPages.cshtml)
@ -136,7 +140,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(871, 128, false);
TagHelper - (871:35,8 [128] RazorPages.cshtml) - div - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(910, 83, true);
HtmlContent - (910:35,47 [83] RazorPages.cshtml)
@ -150,8 +154,9 @@ Document -
IntermediateToken - (983:36,71 [10] RazorPages.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -160,8 +165,9 @@ Document -
IntermediateToken - (999:37,14 [6] RazorPages.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - DivTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - DivTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -

View File

@ -14,6 +14,8 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
private global::AllTagHelper __AllTagHelper;
private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -23,8 +25,6 @@ global::System.Object __typeHelper = "*, AppCode";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper __AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper = null;
private global::AllTagHelper __AllTagHelper = null;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
@ -34,14 +34,14 @@ global::System.Object __typeHelper = "*, AppCode";
#line default
#line hidden
__AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper = CreateTagHelper<global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper>();
__AllTagHelper = CreateTagHelper<global::AllTagHelper>();
__TestViewComponentTagHelper = CreateTagHelper<global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper>();
#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml"
__o = foo;
#line default
#line hidden
__AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper.firstName = string.Empty;
__TestViewComponentTagHelper.firstName = string.Empty;
__AllTagHelper.Bar = " World";
}
#pragma warning restore 1998

View File

@ -11,6 +11,9 @@ Document -
UsingDirective - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper
FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper
DesignTimeDirective -
DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (294:7,71 [4] ) - Html
@ -28,7 +31,6 @@ Document -
DirectiveToken - (14:0,14 [12] ViewComponentTagHelper.cshtml) - "*, AppCode"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper - AllTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (26:0,26 [2] ViewComponentTagHelper.cshtml)
IntermediateToken - (26:0,26 [2] ViewComponentTagHelper.cshtml) - Html - \n
@ -37,15 +39,16 @@ Document -
HtmlContent - (59:4,0 [2] ViewComponentTagHelper.cshtml)
IntermediateToken - (59:4,0 [2] ViewComponentTagHelper.cshtml) - Html - \n
TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper
CreateTagHelper - - AllTagHelper
SetTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - firstName - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - AllTagHelper
DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper
DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml)
IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo
SetTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - bar - Bar - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - bar - string AllTagHelper.Bar - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (93:5,32 [6] ViewComponentTagHelper.cshtml)
IntermediateToken - (93:5,32 [6] ViewComponentTagHelper.cshtml) - Html - World
DefaultTagHelperExecute -
Inject -
Inject -
Inject -

View File

@ -1,19 +1,19 @@
Source Location: (14:0,14 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml)
|"*, AppCode"|
Generated Location: (921:19,37 [12] )
Generated Location: (1168:21,37 [12] )
|"*, AppCode"|
Source Location: (30:1,2 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml)
|
var foo = "Hello";
|
Generated Location: (1663:31,2 [26] )
Generated Location: (1538:31,2 [26] )
|
var foo = "Hello";
|
Source Location: (83:5,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml)
|foo|
Generated Location: (2232:39,22 [3] )
Generated Location: (1996:39,22 [3] )
|foo|

View File

@ -14,12 +14,13 @@ namespace AspNetCore
using Microsoft.AspNetCore.Mvc.ViewFeatures;
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
{
private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper __TestViewComponentTagHelper;
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("bar", " World", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -33,8 +34,7 @@ namespace AspNetCore
return __backed__tagHelperScopeManager;
}
}
private global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper __AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper = null;
private global::AllTagHelper __AllTagHelper = null;
private global::AllTagHelper __AllTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
@ -51,10 +51,10 @@ namespace AspNetCore
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
}
);
__AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper = CreateTagHelper<global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper>();
__tagHelperExecutionContext.Add(__AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper);
__AllTagHelper = CreateTagHelper<global::AllTagHelper>();
__tagHelperExecutionContext.Add(__AllTagHelper);
__TestViewComponentTagHelper = CreateTagHelper<global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper>();
__tagHelperExecutionContext.Add(__TestViewComponentTagHelper);
BeginWriteTagHelperAttribute();
#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ViewComponentTagHelper.cshtml"
WriteLiteral(foo);
@ -62,8 +62,8 @@ namespace AspNetCore
#line default
#line hidden
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper.firstName = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute("first-name", __AspNetCore_TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml___Generated__TestViewComponentTagHelper.firstName, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
__TestViewComponentTagHelper.firstName = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute("first-name", __TestViewComponentTagHelper.firstName, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
__AllTagHelper.Bar = (string)__tagHelperAttribute_0.Value;
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);

View File

@ -10,8 +10,10 @@ Document -
UsingDirective - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingDirective - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_0 - bar - World - HtmlAttributeValueStyle.DoubleQuotes
DeclareTagHelperFields - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper - AllTagHelper
FieldDeclaration - - private - global::AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper - __TestViewComponentTagHelper
PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - bar - World - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::AllTagHelper - __AllTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode - (30:1,2 [26] ViewComponentTagHelper.cshtml)
IntermediateToken - (30:1,2 [26] ViewComponentTagHelper.cshtml) - CSharp - \n var foo = "Hello";\n
@ -24,13 +26,14 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(61, 50, false);
TagHelper - (61:5,0 [50] ViewComponentTagHelper.cshtml) - vc:test - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper
CreateTagHelper - - AllTagHelper
SetTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - firstName - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - AllTagHelper
DefaultTagHelperCreate - - AspNetCore.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ViewComponentTagHelper_cshtml.__Generated__TestViewComponentTagHelper
DefaultTagHelperProperty - (82:5,21 [4] ViewComponentTagHelper.cshtml) - first-name - string TestViewComponentTagHelper.firstName - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression - (83:5,22 [3] ViewComponentTagHelper.cshtml)
IntermediateToken - (83:5,22 [3] ViewComponentTagHelper.cshtml) - CSharp - foo
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_0 - bar - Bar
PreallocatedTagHelperProperty - (93:5,32 [6] ViewComponentTagHelper.cshtml) - __tagHelperAttribute_0 - bar - Bar
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
Inject -

View File

@ -11,9 +11,9 @@ namespace Razor
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("foo"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -27,8 +27,8 @@ namespace Razor
return __backed__tagHelperScopeManager;
}
}
private global::FormTagHelper __FormTagHelper = null;
private global::InputTagHelper __InputTagHelper = null;
private global::FormTagHelper __FormTagHelper;
private global::InputTagHelper __InputTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,10 +1,12 @@
Document -
NamespaceDeclaration - - Razor
ClassDeclaration - - public - Template - -
DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - type - text - AttributeStructure.SingleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - unbound - foo - AttributeStructure.DoubleQuotes
DeclareTagHelperFields - - FormTagHelper - InputTagHelper
PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::FormTagHelper - __FormTagHelper
FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpCode -
IntermediateToken - - CSharp - BeginContext(31, 28, true);
@ -32,7 +34,7 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(71, 87, false);
TagHelper - (71:3,0 [87] BasicTest.cshtml) - form - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(91, 6, true);
HtmlContent - (91:3,20 [6] BasicTest.cshtml)
@ -42,13 +44,14 @@ Document -
CSharpCode -
IntermediateToken - - CSharp - BeginContext(97, 52, false);
TagHelper - (97:4,4 [52] BasicTest.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - InputTagHelper
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_0 - value - FooProp
SetTagHelperProperty - (121:4,28 [13] BasicTest.cshtml) - date - BarProp - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - InputTagHelper
PreallocatedTagHelperProperty - (110:4,17 [5] BasicTest.cshtml) - __tagHelperAttribute_0 - value - FooProp
DefaultTagHelperProperty - (121:4,28 [13] BasicTest.cshtml) - date - System.DateTime InputTagHelper.BarProp - HtmlAttributeValueStyle.DoubleQuotes
CSharpExpression - (122:4,29 [12] BasicTest.cshtml)
IntermediateToken - (122:4,29 [12] BasicTest.cshtml) - CSharp - DateTime.Now
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -
@ -57,8 +60,9 @@ Document -
IntermediateToken - (149:4,56 [2] BasicTest.cshtml) - Html - \n
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CreateTagHelper - - FormTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - FormTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -
CSharpCode -
IntermediateToken - - CSharp - EndContext();
CSharpCode -

View File

@ -1,10 +1,11 @@
// 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.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Extensions;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.CodeAnalysis.Razor;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
@ -22,6 +23,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
.TypeName("TestTagHelper")
.BoundAttributeDescriptor(attribute => attribute
.Name("Foo")
.TypeName("System.Int32"))
@ -42,7 +44,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
// Assert
var @class = FindClassNode(irDocument);
Assert.Equal(2, @class.Children.Count); // No class node created for a VCTH
Assert.Equal(3, @class.Children.Count); // No class node created for a VCTH
for (var i = 0; i < @class.Children.Count; i++)
{
Assert.IsNotType<CSharpCodeIntermediateNode>(@class.Children[i]);
@ -60,6 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly")
.TypeName("__Generated__TagCloudViewComponentTagHelper")
.BoundAttributeDescriptor(attribute => attribute
.Name("Foo")
.TypeName("System.Int32")
@ -77,21 +80,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
var irDocument = CreateIRDocument(engine, codeDocument);
var expectedVCTHName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
var vcthFullName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var tagHelper = FindTagHelperNode(irDocument);
Assert.Equal(expectedVCTHName, Assert.IsType<CreateTagHelperIntermediateNode>(tagHelper.Children[1]).TagHelperTypeName);
Assert.Equal(expectedVCTHName, Assert.IsType<SetTagHelperPropertyIntermediateNode>(tagHelper.Children[2]).TagHelperTypeName);
Assert.Equal(vcthFullName, Assert.IsType<DefaultTagHelperCreateIntermediateNode>(tagHelper.Children[1]).Type);
Assert.Equal("Foo", Assert.IsType<DefaultTagHelperPropertyIntermediateNode>(tagHelper.Children[2]).Property);
var @class = FindClassNode(irDocument);
Assert.Equal(3, @class.Children.Count);
Assert.Equal(4, @class.Children.Count);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children[2]);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children.Last());
var tokenNode = vcthClass.Children[0] as IntermediateToken;
Assert.Equal(
@"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")]
@ -130,6 +133,7 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
var tagHelpers = new[]
{
TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly")
.TypeName("__Generated__TagCloudViewComponentTagHelper")
.BoundAttributeDescriptor(attribute => attribute
.Name("Foo")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
@ -148,20 +152,20 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
var irDocument = CreateIRDocument(engine, codeDocument);
var expectedVCTHName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
var vcthFullName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var tagHelper = FindTagHelperNode(irDocument);
Assert.Equal(expectedVCTHName, Assert.IsType<CreateTagHelperIntermediateNode>(tagHelper.Children[1]).TagHelperTypeName);
Assert.IsType<AddTagHelperHtmlAttributeIntermediateNode>(tagHelper.Children[2]);
Assert.Equal(vcthFullName, Assert.IsType<DefaultTagHelperCreateIntermediateNode>(tagHelper.Children[1]).Type);
Assert.IsType<DefaultTagHelperHtmlAttributeIntermediateNode>(tagHelper.Children[2]);
var @class = FindClassNode(irDocument);
Assert.Equal(3, @class.Children.Count);
Assert.Equal(4, @class.Children.Count);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children[2]);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children[3]);
var tokenNode = vcthClass.Children[0] as IntermediateToken;
Assert.Equal(
@"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")]
@ -202,18 +206,18 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
{
TagHelperDescriptorBuilder.Create("PTestTagHelper", "TestAssembly")
.TypeName("PTestTagHelper")
.BoundAttributeDescriptor(attribute =>
attribute
.Name("Foo")
.TypeName("System.Int32"))
.TagMatchingRuleDescriptor(rule =>
rule.RequireTagName("p"))
.BoundAttributeDescriptor(attribute => attribute
.PropertyName("Foo")
.Name("Foo")
.TypeName("System.Int32"))
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
.Build(),
TagHelperDescriptorBuilder.Create(ViewComponentTagHelperConventions.Kind, "TestTagHelper", "TestAssembly")
.TypeName("__Generated__TagCloudViewComponentTagHelper")
.BoundAttributeDescriptor(attribute => attribute
.PropertyName("Foo")
.Name("Foo")
.TypeName("System.Int32")
.PropertyName("Foo"))
.TypeName("System.Int32"))
.TagMatchingRuleDescriptor(rule => rule.RequireTagName("tagcloud"))
.AddMetadata(ViewComponentTagHelperMetadata.Name, "TagCloud")
.Build()
@ -226,27 +230,26 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
};
var irDocument = CreateIRDocument(engine, codeDocument);
var expectedTagHelperName = "PTestTagHelper";
var expectedVCTHName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
var vcthFullName = "AspNetCore.test_cshtml.__Generated__TagCloudViewComponentTagHelper";
// Act
pass.Execute(codeDocument, irDocument);
// Assert
var outerTagHelper = FindTagHelperNode(irDocument);
Assert.Equal(expectedTagHelperName, Assert.IsType<CreateTagHelperIntermediateNode>(outerTagHelper.Children[1]).TagHelperTypeName);
Assert.Equal(expectedTagHelperName, Assert.IsType<SetTagHelperPropertyIntermediateNode>(outerTagHelper.Children[2]).TagHelperTypeName);
Assert.Equal("PTestTagHelper", Assert.IsType<DefaultTagHelperCreateIntermediateNode>(outerTagHelper.Children[1]).Type);
Assert.Equal("Foo", Assert.IsType<DefaultTagHelperPropertyIntermediateNode>(outerTagHelper.Children[2]).Property);
var vcth = FindTagHelperNode(outerTagHelper.Children[0]);
Assert.Equal(expectedVCTHName, Assert.IsType<CreateTagHelperIntermediateNode>(vcth.Children[1]).TagHelperTypeName);
Assert.Equal(expectedVCTHName, Assert.IsType<SetTagHelperPropertyIntermediateNode>(vcth.Children[2]).TagHelperTypeName);
Assert.Equal(vcthFullName, Assert.IsType<DefaultTagHelperCreateIntermediateNode>(vcth.Children[1]).Type);
Assert.Equal("Foo", Assert.IsType<DefaultTagHelperPropertyIntermediateNode>(vcth.Children[2]).Property);
var @class = FindClassNode(irDocument);
Assert.Equal(3, @class.Children.Count);
Assert.Equal(5, @class.Children.Count);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children[2]);
var vcthClass = Assert.IsType<CSharpCodeIntermediateNode>(@class.Children.Last());
var tokenNode = vcthClass.Children[0] as IntermediateToken;
Assert.Equal(
@"[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute(""tagcloud"")]
@ -303,6 +306,12 @@ public class __Generated__TagCloudViewComponentTagHelper : Microsoft.AspNetCore.
}
}
// We also expect the default tag helper pass to run first.
var documentNode = codeDocument.GetDocumentIntermediateNode();
var defaultTagHelperPass = engine.Features.OfType<DefaultTagHelperOptimizationPass>().Single();
defaultTagHelperPass.Execute(codeDocument, documentNode);
return codeDocument.GetDocumentIntermediateNode();
}

View File

@ -1,264 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class DesignTimeTagHelperWriterTest
{
[Fact]
public void WriteDeclareTagHelperFields_DeclaresUsedTagHelperTypes()
{
// Arrange
var writer = new DesignTimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
var node = new DeclareTagHelperFieldsIntermediateNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"private global::PTagHelper __PTagHelper = null;
private global::MyTagHelper __MyTagHelper = null;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCreateTagHelper_RendersCorrectly_UsesSpecifiedTagHelperType()
{
// Arrange
var writer = new DesignTimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
var node = new CreateTagHelperIntermediateNode()
{
TagHelperTypeName = "TestNamespace.MyTagHelper"
};
// Act
writer.WriteCreateTagHelper(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.String"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input bound=""value"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
__InputTagHelper.FooProp = ""value"";
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_NonStringAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Int32"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input bound=""42"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.FooProp = 42;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_IndexerAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionaryAttribute("foo-", "System.Int32"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input foo-bound=""42"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.FooProp[""bound""] = 42;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CodeRenderingContext GetCodeRenderingContext(TagHelperWriter writer, RazorCodeDocument codeDocument = null)
{
var options = RazorCodeGenerationOptions.CreateDefault();
var codeWriter = new CodeWriter();
var nodeWriter = new DesignTimeNodeWriter();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, codeDocument?.Source, options)
{
TagHelperWriter = writer,
TagHelperRenderingContext = new TagHelperRenderingContext()
};
context.SetRenderChildren(n =>
{
codeWriter.WriteLine("Render Children");
});
return context;
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorIntermediateNodeLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetDocumentIntermediateNode();
Assert.NotNull(irDocument);
return irDocument;
}
private static TagHelperDescriptor CreateTagHelperDescriptor(
string tagName,
string typeName,
string assemblyName,
IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
{
var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
builder.TypeName(typeName);
if (attributes != null)
{
foreach (var attributeBuilder in attributes)
{
builder.BoundAttributeDescriptor(attributeBuilder);
}
}
builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
var descriptor = builder.Build();
return descriptor;
}
}
}

View File

@ -1,501 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class RuntimeTagHelperWriterTest
{
[Fact]
public void WriteDeclareTagHelperFields_DeclaresRequiredFields()
{
// Arrange
var node = new DeclareTagHelperFieldsIntermediateNode();
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDeclareTagHelperFields_DeclaresUsedTagHelperTypes()
{
// Arrange
var node = new DeclareTagHelperFieldsIntermediateNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
private global::PTagHelper __PTagHelper = null;
private global::MyTagHelper __MyTagHelper = null;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperBody_RendersCorrectly_UsesTagNameAndModeFromContext()
{
// Arrange
var node = new TagHelperBodyIntermediateNode();
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
context.Items[CodeRenderingContext.SuppressUniqueIds] = "test";
context.TagHelperRenderingContext = new TagHelperRenderingContext()
{
TagName = "p",
TagMode = TagMode.SelfClosing
};
// Act
writer.WriteTagHelperBody(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__tagHelperExecutionContext = __tagHelperScopeManager.Begin(""p"", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, ""test"", async() => {
Render Children
}
);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCreateTagHelper_RendersCorrectly_UsesSpecifiedTagHelperType()
{
// Arrange
var node = new CreateTagHelperIntermediateNode()
{
TagHelperTypeName = "TestNamespace.MyTagHelper"
};
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
// Act
writer.WriteCreateTagHelper(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
__tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelper_RendersCorrectly_SetsTagNameAndModeInContext()
{
// Arrange
var node = new TagHelperIntermediateNode();
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer);
// Act
writer.WriteTagHelper(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteAddTagHelperHtmlAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly")
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input name=""value"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__tagHelperExecutionContext.AddHtmlAttribute(""name"", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteAddTagHelperHtmlAttribute_DataAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly")
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input data-test=""Blah-@Foo"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__tagHelperExecutionContext.AddHtmlAttribute(""data-test"", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteAddTagHelperHtmlAttribute_DynamicAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly")
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input test=""Blah-@Foo"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"BeginAddHtmlAttributeValues(__tagHelperExecutionContext, ""test"", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
Render Children
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.String"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input bound=""value"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
// The attribute value is not rendered inline because we are not using the preallocated writer.
Assert.Equal(
@"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__InputTagHelper.FooProp = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.FooProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_NonStringAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Int32"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input bound=""42"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.FooProp = 42;
#line default
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.FooProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_IndexerAttribute_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionaryAttribute("foo-", "System.Int32"),
})
};
var engine = RazorEngine.Create(builder => builder.AddTagHelpers(descriptors));
var content = @"
@addTagHelper *, TestAssembly
<input foo-bound=""42"" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as SetTagHelperPropertyIntermediateNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCodeRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"if (__InputTagHelper.FooProp == null)
{
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""FooProp""));
}
#line 3 ""test.cshtml""
__InputTagHelper.FooProp[""bound""] = 42;
#line default
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.FooProp[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CodeRenderingContext GetCodeRenderingContext(TagHelperWriter writer, RazorCodeDocument codeDocument = null)
{
var codeWriter = new CodeWriter();
var nodeWriter = new RuntimeNodeWriter();
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, codeDocument?.Source, options)
{
TagHelperWriter = writer,
TagHelperRenderingContext = new TagHelperRenderingContext()
};
context.SetRenderChildren(n =>
{
codeWriter.WriteLine("Render Children");
});
return context;
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorIntermediateNodeLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetDocumentIntermediateNode();
Assert.NotNull(irDocument);
return irDocument;
}
private static TagHelperDescriptor CreateTagHelperDescriptor(
string tagName,
string typeName,
string assemblyName,
IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
{
var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
builder.TypeName(typeName);
if (attributes != null)
{
foreach (var attributeBuilder in attributes)
{
builder.BoundAttributeDescriptor(attributeBuilder);
}
}
builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
var descriptor = builder.Build();
return descriptor;
}
}
}

View File

@ -198,14 +198,12 @@ namespace Microsoft.AspNetCore.Razor.Language
SyntaxConstants.CSharp.AddTagHelperKeyword,
n,
v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
n => TagHelperFieldDeclaration(n, "SpanTagHelper"),
n => TagHelper(
"span",
TagMode.StartTagAndEndTag,
tagHelpers,
n,
c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
c => Assert.IsType<CreateTagHelperIntermediateNode>(c),
c => TagHelperHtmlAttribute(
"val",
AttributeStructure.DoubleQuotes,
@ -242,14 +240,12 @@ namespace Microsoft.AspNetCore.Razor.Language
SyntaxConstants.CSharp.TagHelperPrefixKeyword,
n,
v => DirectiveToken(DirectiveTokenKind.String, "cool:", v)),
n => TagHelperFieldDeclaration(n, "SpanTagHelper"),
n => TagHelper(
"span", // Note: this is span not cool:span
TagMode.StartTagAndEndTag,
tagHelpers,
n,
c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
c => Assert.IsType<CreateTagHelperIntermediateNode>(c),
c => TagHelperHtmlAttribute(
"val",
AttributeStructure.DoubleQuotes,
@ -272,7 +268,7 @@ namespace Microsoft.AspNetCore.Razor.Language
tagName: "span",
typeName: "SpanTagHelper",
assemblyName: "TestAssembly")
};
};
// Act
var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
@ -295,15 +291,13 @@ namespace Microsoft.AspNetCore.Razor.Language
tagHelpers,
c1,
c2 => Assert.IsType<TagHelperBodyIntermediateNode>(c2),
c2 => Assert.IsType<CreateTagHelperIntermediateNode>(c2),
c2 => TagHelperHtmlAttribute(
"val",
AttributeStructure.DoubleQuotes,
c2,
v => CSharpExpressionAttributeValue(string.Empty, "Hello", v),
v => LiteralAttributeValue(" ", "World", v))),
c1 => Html(Environment.NewLine, c1)),
n => TagHelperFieldDeclaration(n, "SpanTagHelper"));
c1 => Html(Environment.NewLine, c1)));
}
[Fact]
@ -314,18 +308,18 @@ namespace Microsoft.AspNetCore.Razor.Language
<input bound='foo' />");
var tagHelpers = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.String"),
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.String"),
})
};
};
// Act
var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
@ -337,14 +331,12 @@ namespace Microsoft.AspNetCore.Razor.Language
SyntaxConstants.CSharp.AddTagHelperKeyword,
n,
v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
n => TagHelperFieldDeclaration(n, "InputTagHelper"),
n => TagHelper(
"input",
TagMode.SelfClosing,
tagHelpers,
n,
c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
c => Assert.IsType<CreateTagHelperIntermediateNode>(c),
c => SetTagHelperProperty(
"bound",
"FooProp",

View File

@ -143,33 +143,6 @@ namespace Microsoft.AspNetCore.Razor.Language
n => Assert.IsType<ClassDeclarationIntermediateNode>(n));
}
[Fact]
public void Execute_AddsTagHelperFieldsToClass()
{
// Arrange
var documentNode = new DocumentIntermediateNode()
{
Options = RazorCodeGenerationOptions.CreateDefault(),
};
var builder = IntermediateNodeBuilder.Create(documentNode);
builder.Add(new DeclareTagHelperFieldsIntermediateNode());
var pass = new TestDocumentClassifierPass();
pass.Engine = RazorEngine.CreateEmpty(b => { });
// Act
pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
// Assert
var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
Children(
@class,
n => Assert.IsType<DeclareTagHelperFieldsIntermediateNode>(n),
n => Assert.IsType<MethodDeclarationIntermediateNode>(n));
}
[Fact]
public void Execute_AddsTheRestToMethod()
{

View File

@ -0,0 +1,926 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.Extensions
{
public class DefaultTagHelperTargetExtensionTest
{
private static readonly TagHelperDescriptor StringPropertyTagHelper = CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("StringProp")
.TypeName("System.String"),
});
private static readonly TagHelperDescriptor IntPropertyTagHelper = CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("IntProp")
.TypeName("System.Int32"),
});
private static readonly TagHelperDescriptor StringIndexerTagHelper = CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("StringIndexer")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
.AsDictionary("foo-", "System.String"),
});
private static readonly TagHelperDescriptor IntIndexerTagHelper = CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<BoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("IntIndexer")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionary("foo-", "System.Int32"),
});
private static readonly SourceSpan Span = new SourceSpan("test.cshtml", 15, 2, 5, 2);
[Fact]
public void WriteTagHelperBody_DesignTime_WritesChildren()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperBodyIntermediateNode();
// Act
extension.WriteTagHelperBody(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperBody_Runtime_RendersCorrectly_UsesTagNameAndModeFromContext()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
context.TagHelperRenderingContext.TagMode = TagMode.SelfClosing;
context.TagHelperRenderingContext.TagName = "p";
var node = new DefaultTagHelperBodyIntermediateNode();
// Act
extension.WriteTagHelperBody(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__tagHelperExecutionContext = __tagHelperScopeManager.Begin(""p"", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, ""test"", async() => {
Render Children
}
);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperCreate_DesignTime_RendersCorrectly_UsesSpecifiedTagHelperType()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperCreateIntermediateNode()
{
Field = "__TestNamespace_MyTagHelper",
Type = "TestNamespace.MyTagHelper",
};
// Act
extension.WriteTagHelperCreate(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperCreate_Runtime_RendersCorrectly_UsesSpecifiedTagHelperType()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperCreateIntermediateNode()
{
Field = "__TestNamespace_MyTagHelper",
Type = "TestNamespace.MyTagHelper",
};
// Act
extension.WriteTagHelperCreate(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
__tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperExecute_DesignTime_WritesNothing()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperExecuteIntermediateNode();
// Act
extension.WriteTagHelperExecute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperExecute_Runtime_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperExecuteIntermediateNode();
// Act
extension.WriteTagHelperExecute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperHtmlAttribute_DesignTime_WritesNothing()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
{
AttributeName = "name",
AttributeStructure = AttributeStructure.DoubleQuotes,
Children =
{
new HtmlAttributeValueIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.Html, Content = "Blah-" } }
},
new CSharpCodeAttributeValueIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "\"Foo\"", } },
}
}
};
// Act
extension.WriteTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperHtmlAttribute_Runtime_SimpleAttribute_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
{
AttributeName = "name",
AttributeStructure = AttributeStructure.DoubleQuotes,
Children =
{
new HtmlAttributeIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.Html, Content = "\"value\"", } },
}
}
};
// Act
extension.WriteTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__tagHelperExecutionContext.AddHtmlAttribute(""name"", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperHtmlAttribute_Runtime_DynamicAttribute_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
{
AttributeName = "name",
AttributeStructure = AttributeStructure.DoubleQuotes,
Children =
{
new HtmlAttributeValueIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.Html, Content = "Blah-" } }
},
new CSharpCodeAttributeValueIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "\"Foo\"", } },
}
}
};
// Act
extension.WriteTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"BeginAddHtmlAttributeValues(__tagHelperExecutionContext, ""name"", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
Render Children
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_DesignTime_StringProperty_HtmlContent_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "StringProp",
TagHelper = StringPropertyTagHelper,
Children =
{
new HtmlContentIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.Html, Content = "value", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
__InputTagHelper.StringProp = ""value"";
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact] // We don't actually assign the expression result at design time, we just use string.Empty as a placeholder.
public void WriteTagHelperProperty_DesignTime_StringProperty_NonHtmlContent_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "StringProp",
TagHelper = StringPropertyTagHelper,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "\"3+5\"", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"Render Children
__InputTagHelper.StringProp = string.Empty;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_DesignTime_NonStringProperty_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "IntProp",
TagHelper = IntPropertyTagHelper,
Source = Span,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.IntProp = 32;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_DesignTime_NonStringProperty_RendersCorrectly_WithoutLocation()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "IntProp",
TagHelper = IntPropertyTagHelper,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__InputTagHelper.IntProp = 32;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_DesignTime_NonStringIndexer_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "foo-bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = true,
Property = "IntIndexer",
TagHelper = IntIndexerTagHelper,
Source = Span,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.IntIndexer[""bound""] = 32;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_DesignTime_NonStringIndexer_RendersCorrectly_WithoutLocation()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "foo-bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = true,
Property = "IntIndexer",
TagHelper = IntIndexerTagHelper,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__InputTagHelper.IntIndexer[""bound""] = 32;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_Runtime_StringProperty_HtmlContent_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "StringProp",
TagHelper = StringPropertyTagHelper,
Children =
{
new HtmlContentIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.Html, Content = "\"value\"", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
// The attribute value is not rendered inline because we are not using the preallocated writer.
Assert.Equal(
@"BeginWriteTagHelperAttribute();
Render Children
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__InputTagHelper.StringProp = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.StringProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_Runtime_NonStringProperty_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "IntProp",
TagHelper = IntPropertyTagHelper,
Source = Span,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
},
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.IntProp = 32;
#line default
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.IntProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_Runtime_NonStringProperty_RendersCorrectly_WithoutLocation()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = false,
Property = "IntProp",
TagHelper = IntPropertyTagHelper,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"__InputTagHelper.IntProp = 32;
__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.IntProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_Runtime_NonStringIndexer_RendersCorrectly()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "foo-bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = true,
Property = "IntIndexer",
TagHelper = IntIndexerTagHelper,
Source = Span,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"if (__InputTagHelper.IntIndexer == null)
{
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""IntIndexer""));
}
#line 3 ""test.cshtml""
__InputTagHelper.IntIndexer[""bound""] = 32;
#line default
#line hidden
__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperProperty_Runtime_NonStringIndexer_RendersCorrectly_WithoutLocation()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperPropertyIntermediateNode()
{
AttributeName = "foo-bound",
AttributeStructure = AttributeStructure.DoubleQuotes,
BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
Field = "__InputTagHelper",
IsIndexerNameMatch = true,
Property = "IntIndexer",
TagHelper = IntIndexerTagHelper,
Children =
{
new CSharpExpressionIntermediateNode()
{
Children = { new IntermediateToken { Kind = IntermediateToken.TokenKind.CSharp, Content = "32", } },
}
}
};
// Act
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"if (__InputTagHelper.IntIndexer == null)
{
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""IntIndexer""));
}
__InputTagHelper.IntIndexer[""bound""] = 32;
__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperRuntime_DesignTime_WritesNothing()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension() { DesignTime = true };
var context = GetDesignTimeCodeRenderingContext();
var node = new DefaultTagHelperRuntimeIntermediateNode();
// Act
extension.WriteTagHelperRuntime(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteTagHelperRuntime_Runtime_DeclaresRequiredFields()
{
// Arrange
var extension = new DefaultTagHelperTargetExtension();
var context = GetRuntimeCodeRenderingContext();
var node = new DefaultTagHelperRuntimeIntermediateNode();
// Act
extension.WriteTagHelperRuntime(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
Assert.Equal(
@"#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CodeRenderingContext GetRuntimeCodeRenderingContext()
{
var codeWriter = new CodeWriter();
var nodeWriter = new RuntimeNodeWriter();
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, null, options)
{
Items =
{
{ CodeRenderingContext.SuppressUniqueIds, "test" },
},
TagHelperWriter = new RuntimeTagHelperWriter(),
TagHelperRenderingContext = new TagHelperRenderingContext()
};
context.SetRenderChildren(n =>
{
codeWriter.WriteLine("Render Children");
});
return context;
}
private static CodeRenderingContext GetDesignTimeCodeRenderingContext()
{
var codeWriter = new CodeWriter();
var nodeWriter = new RuntimeNodeWriter();
var options = RazorCodeGenerationOptions.CreateDesignTimeDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, null, options)
{
Items =
{
{ CodeRenderingContext.SuppressUniqueIds, "test" },
},
TagHelperWriter = new DesignTimeTagHelperWriter(),
TagHelperRenderingContext = new TagHelperRenderingContext()
};
context.SetRenderChildren(n =>
{
codeWriter.WriteLine("Render Children");
});
return context;
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIntermediateNode LowerDesignTime(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.CreateDesignTime();
return Lower(codeDocument, engine);
}
private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
{
for (var i = 0; i < engine.Phases.Count; i++)
{
var phase = engine.Phases[i];
phase.Execute(codeDocument);
if (phase is IRazorIntermediateNodeLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetDocumentIntermediateNode();
Assert.NotNull(irDocument);
return irDocument;
}
private static TagHelperDescriptor CreateTagHelperDescriptor(
string tagName,
string typeName,
string assemblyName,
IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
{
var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
builder.TypeName(typeName);
if (attributes != null)
{
foreach (var attributeBuilder in attributes)
{
builder.BindAttribute(attributeBuilder);
}
}
builder.TagMatchingRule(ruleBuilder => ruleBuilder.RequireTagName(tagName));
var descriptor = builder.Build();
return descriptor;
}
}
}

View File

@ -18,16 +18,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, sourceDocument: null, options: options);
var node = new DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode()
var node = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode()
{
Name = "Foo",
AttributeName = "Foo",
Value = "Bar",
AttributeStructure = AttributeStructure.DoubleQuotes,
VariableName = "MyProp"
};
// Act
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, node);
extension.WriteTagHelperHtmlAttributeValue(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
@ -48,16 +48,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, sourceDocument: null, options: options);
var node = new DeclarePreallocatedTagHelperHtmlAttributeIntermediateNode()
var node = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode()
{
Name = "Foo",
AttributeName = "Foo",
Value = "Bar",
AttributeStructure = AttributeStructure.Minimized,
VariableName = "_tagHelper1"
};
// Act
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, node);
extension.WriteTagHelperHtmlAttributeValue(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
@ -78,13 +78,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, sourceDocument: null, options: options);
var node = new AddPreallocatedTagHelperHtmlAttributeIntermediateNode()
var node = new PreallocatedTagHelperHtmlAttributeIntermediateNode()
{
VariableName = "_tagHelper1"
};
// Act
extension.WriteAddPreallocatedTagHelperHtmlAttribute(context, node);
extension.WriteTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
@ -105,16 +105,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var options = RazorCodeGenerationOptions.CreateDefault();
var context = new DefaultCodeRenderingContext(codeWriter, nodeWriter, sourceDocument: null, options: options);
var node = new DeclarePreallocatedTagHelperAttributeIntermediateNode()
var node = new PreallocatedTagHelperPropertyValueIntermediateNode()
{
Name = "Foo",
AttributeName = "Foo",
Value = "Bar",
AttributeStructure = AttributeStructure.DoubleQuotes,
VariableName = "_tagHelper1",
};
// Act
extension.WriteDeclarePreallocatedTagHelperAttribute(context, node);
extension.WriteTagHelperPropertyValue(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
@ -147,16 +147,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
var descriptor = builder.Build();
var node = new SetPreallocatedTagHelperPropertyIntermediateNode()
var node = new PreallocatedTagHelperPropertyIntermediateNode()
{
AttributeName = descriptor.Name,
TagHelperTypeName = "FooTagHelper",
Field = "__FooTagHelper",
VariableName = "_tagHelper1",
Descriptor = descriptor,
BoundAttribute = descriptor,
};
// Act
extension.WriteSetPreallocatedTagHelperProperty(context, node);
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();
@ -194,17 +194,18 @@ __tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
var descriptor = builder.Build();
var node = new SetPreallocatedTagHelperPropertyIntermediateNode()
var node = new PreallocatedTagHelperPropertyIntermediateNode()
{
AttributeName = "pre-Foo",
TagHelperTypeName = "FooTagHelper",
Field = "__FooTagHelper",
VariableName = "_tagHelper1",
Descriptor = descriptor,
IsIndexerNameMatch = true
BoundAttribute = descriptor,
IsIndexerNameMatch = true,
TagHelper = tagHelperBuilder.Build(),
};
// Act
extension.WriteSetPreallocatedTagHelperProperty(context, node);
extension.WriteTagHelperProperty(context, node);
// Assert
var csharp = context.CodeWriter.Builder.ToString();

View File

@ -406,7 +406,7 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
builder => builder
.Name("int-dictionary")
.PropertyName("IntDictionaryProperty")
.TypeName(typeof(IDictionary<string, int>).FullName)
.TypeName("System.Collections.Generic.IDictionary<string, int>")
.AsDictionaryAttribute("int-prefix-", typeof(int).FullName),
builder => builder
.Name("string-prefix-grabber")

View File

@ -87,6 +87,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
WasSpecificMethodCalled = true;
}
}
}
}
}

View File

@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.IsType<DefaultRazorEngine>(engine);
AssertDefaultRuntimeFeatures(engine.Features);
AssertDefaultRuntimePhases(engine.Phases);
AssertDefaultRuntimeTargetExtensions(engine);
}
[Fact]
@ -35,6 +36,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.IsType<DefaultRazorEngine>(engine);
AssertDefaultDesignTimeFeatures(engine.Features);
AssertDefaultDesignTimePhases(engine.Phases);
AssertDefaultDesignTimeTargetExtensions(engine);
}
[Fact]
@ -48,6 +50,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.IsType<DefaultRazorEngine>(engine);
AssertDefaultRuntimeFeatures(engine.Features);
AssertDefaultRuntimePhases(engine.Phases);
AssertDefaultRuntimeTargetExtensions(engine);
}
[Fact]
@ -61,6 +64,7 @@ namespace Microsoft.AspNetCore.Razor.Language
Assert.IsType<DefaultRazorEngine>(engine);
AssertDefaultDesignTimeFeatures(engine.Features);
AssertDefaultDesignTimePhases(engine.Phases);
AssertDefaultDesignTimeTargetExtensions(engine);
}
[Fact]
@ -133,12 +137,15 @@ namespace Microsoft.AspNetCore.Razor.Language
p => Assert.Same(phases[1], p));
}
private static void AssertDefaultTargetExtensions(RazorEngine engine)
private static void AssertDefaultRuntimeTargetExtensions(RazorEngine engine)
{
var feature = engine.Features.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
Assert.NotNull(feature);
Assert.Empty(feature.TargetExtensions);
Assert.Collection(
feature.TargetExtensions,
extension => Assert.False(Assert.IsType<DefaultTagHelperTargetExtension>(extension).DesignTime),
extension => Assert.IsType<PreallocatedAttributeTargetExtension>(extension));
}
private static void AssertDefaultRuntimeFeatures(IEnumerable<IRazorEngineFeature> features)
@ -151,6 +158,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
}
@ -169,6 +177,17 @@ namespace Microsoft.AspNetCore.Razor.Language
phase => Assert.IsType<DefaultRazorCSharpLoweringPhase>(phase));
}
private static void AssertDefaultDesignTimeTargetExtensions(RazorEngine engine)
{
var feature = engine.Features.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
Assert.NotNull(feature);
Assert.Collection(
feature.TargetExtensions,
extension => Assert.True(Assert.IsType<DefaultTagHelperTargetExtension>(extension).DesignTime),
extension => Assert.IsType<DesignTimeDirectiveTargetExtension>(extension));
}
private static void AssertDefaultDesignTimeFeatures(IEnumerable<IRazorEngineFeature> features)
{
Assert.Collection(
@ -179,6 +198,7 @@ namespace Microsoft.AspNetCore.Razor.Language
feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
feature => Assert.IsType<DesignTimeOptionsFeature>(feature),
feature => Assert.IsType<DesignTimeDirectivePass>(feature));

View File

@ -5,6 +5,10 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
#line hidden
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_DesignTime
{
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -14,10 +18,6 @@ global::System.Object __typeHelper = "*, TestAssembly";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper = null;
private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper = null;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper = null;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2 = null;
#pragma warning disable 1998
public async System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,27 +1,32 @@
Document -
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_DesignTime - -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
DesignTimeDirective -
DirectiveToken - (14:0,14 [15] AttributeTargetingTagHelpers.cshtml) - *, TestAssembly
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.CatchAllTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (29:0,29 [4] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (29:0,29 [4] AttributeTargetingTagHelpers.cshtml) - Html - \n\n
TagHelper - (33:2,0 [228] AttributeTargetingTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (48:2,15 [9] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (48:2,15 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
IntermediateToken - (54:3,4 [3] AttributeTargetingTagHelpers.cshtml) - Html - <p>
TagHelper - (57:3,7 [36] AttributeTargetingTagHelpers.cshtml) - strong - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml) - Html - Hello
CreateTagHelper - - TestNamespace.CatchAllTagHelper
AddTagHelperHtmlAttribute - - catchAll - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
DefaultTagHelperHtmlAttribute - - catchAll - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (75:3,25 [2] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (75:3,25 [2] AttributeTargetingTagHelpers.cshtml) - Html - hi
DefaultTagHelperExecute -
HtmlContent - (93:3,43 [62] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (93:3,43 [8] AttributeTargetingTagHelpers.cshtml) - Html - <strong>
IntermediateToken - (101:3,51 [5] AttributeTargetingTagHelpers.cshtml) - Html - World
@ -33,38 +38,41 @@ Document -
IntermediateToken - (146:4,25 [3] AttributeTargetingTagHelpers.cshtml) - Html - />
IntermediateToken - (149:4,28 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
TagHelper - (155:5,4 [40] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
SetTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
DefaultTagHelperExecute -
HtmlContent - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
TagHelper - (201:6,4 [54] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
CreateTagHelper - - TestNamespace.CatchAllTagHelper
SetTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
DefaultTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
AddTagHelperHtmlAttribute - - catchAll - AttributeStructure.DoubleQuotes
DefaultTagHelperHtmlAttribute - - catchAll - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (249:6,52 [2] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (249:6,52 [2] AttributeTargetingTagHelpers.cshtml) - Html - hi
DefaultTagHelperExecute -
HtmlContent - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
CreateTagHelper - - TestNamespace.PTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - TestNamespace.PTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (43:2,10 [3] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (43:2,10 [3] AttributeTargetingTagHelpers.cshtml) - Html - btn
DefaultTagHelperExecute -

View File

@ -1,15 +1,15 @@
Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
|*, TestAssembly|
Generated Location: (435:10,38 [15] )
Generated Location: (779:14,38 [15] )
|*, TestAssembly|
Source Location: (187:5,36 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
|true|
Generated Location: (1679:29,42 [4] )
Generated Location: (1651:29,42 [4] )
|true|
Source Location: (233:6,36 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
|true|
Generated Location: (2332:39,42 [4] )
Generated Location: (2304:39,42 [4] )
|true|

View File

@ -11,9 +11,9 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("btn"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -27,10 +27,10 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
return __backed__tagHelperScopeManager;
}
}
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper = null;
private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper = null;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper = null;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2 = null;
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
#pragma warning disable 1998
public async System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,24 +1,29 @@
Document -
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_Runtime - -
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0 - catchAll - hi - AttributeStructure.DoubleQuotes
DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_1 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2 - class - btn - AttributeStructure.DoubleQuotes
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.CatchAllTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - catchAll - hi - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - btn - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (31:1,0 [2] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (31:1,0 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
TagHelper - (33:2,0 [228] AttributeTargetingTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (48:2,15 [9] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (48:2,15 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
IntermediateToken - (54:3,4 [3] AttributeTargetingTagHelpers.cshtml) - Html - <p>
TagHelper - (57:3,7 [36] AttributeTargetingTagHelpers.cshtml) - strong - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml) - Html - Hello
CreateTagHelper - - TestNamespace.CatchAllTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperExecute -
HtmlContent - (93:3,43 [62] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (93:3,43 [8] AttributeTargetingTagHelpers.cshtml) - Html - <strong>
IntermediateToken - (101:3,51 [5] AttributeTargetingTagHelpers.cshtml) - Html - World
@ -30,26 +35,29 @@ Document -
IntermediateToken - (146:4,25 [3] AttributeTargetingTagHelpers.cshtml) - Html - />
IntermediateToken - (149:4,28 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
TagHelper - (155:5,4 [40] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_1 - type - Type
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_1 - type - Type
SetTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
PreallocatedTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
PreallocatedTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
DefaultTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
DefaultTagHelperExecute -
HtmlContent - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
TagHelper - (201:6,4 [54] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
CreateTagHelper - - TestNamespace.CatchAllTagHelper
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_1 - type - Type
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_1 - type - Type
SetTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
PreallocatedTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
PreallocatedTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
DefaultTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
DefaultTagHelperExecute -
HtmlContent - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml)
IntermediateToken - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
CreateTagHelper - - TestNamespace.PTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperCreate - - TestNamespace.PTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
DefaultTagHelperExecute -

View File

@ -5,6 +5,9 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
#line hidden
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_DesignTime
{
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -14,9 +17,6 @@ global::System.Object __typeHelper = "*, TestAssembly";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper = null;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper = null;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2 = null;
#pragma warning disable 1998
public async System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,11 +1,14 @@
Document -
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_DesignTime - -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] BasicTagHelpers.cshtml) - "*, TestAssembly"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (31:0,31 [73] BasicTagHelpers.cshtml)
IntermediateToken - (31:0,31 [4] BasicTagHelpers.cshtml) - Html - \n\n
@ -17,57 +20,61 @@ Document -
IntermediateToken - (97:2,62 [1] BasicTagHelpers.cshtml) - Html - >
IntermediateToken - (98:2,63 [6] BasicTagHelpers.cshtml) - Html - \n
TagHelper - (104:3,4 [216] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (145:3,45 [10] BasicTagHelpers.cshtml)
IntermediateToken - (145:3,45 [10] BasicTagHelpers.cshtml) - Html - \n
TagHelper - (155:4,8 [25] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
CreateTagHelper - - TestNamespace.PTagHelper
AddTagHelperHtmlAttribute - - data - AttributeStructure.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.PTagHelper
DefaultTagHelperHtmlAttribute - - data - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (164:4,17 [10] BasicTagHelpers.cshtml)
IntermediateToken - (164:4,17 [10] BasicTagHelpers.cshtml) - Html - -delay1000
DefaultTagHelperExecute -
HtmlContent - (180:4,33 [10] BasicTagHelpers.cshtml)
IntermediateToken - (180:4,33 [10] BasicTagHelpers.cshtml) - Html - \n
TagHelper - (190:5,8 [71] BasicTagHelpers.cshtml) - input - TagMode.StartTagOnly
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
AddTagHelperHtmlAttribute - - data-interval - AttributeStructure.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperHtmlAttribute - - data-interval - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (212:5,30 [7] BasicTagHelpers.cshtml)
IntermediateToken - (212:5,30 [7] BasicTagHelpers.cshtml) - Html - 2000 +
CSharpExpression - (220:5,38 [23] BasicTagHelpers.cshtml)
IntermediateToken - (220:5,38 [23] BasicTagHelpers.cshtml) - CSharp - ViewBag.DefaultInterval
HtmlContent - (243:5,61 [4] BasicTagHelpers.cshtml)
IntermediateToken - (243:5,61 [4] BasicTagHelpers.cshtml) - Html - + 1
SetTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (255:5,73 [4] BasicTagHelpers.cshtml)
IntermediateToken - (255:5,73 [4] BasicTagHelpers.cshtml) - Html - text
SetTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (255:5,73 [4] BasicTagHelpers.cshtml)
IntermediateToken - (255:5,73 [4] BasicTagHelpers.cshtml) - Html - text
DefaultTagHelperExecute -
HtmlContent - (261:5,79 [10] BasicTagHelpers.cshtml)
IntermediateToken - (261:5,79 [10] BasicTagHelpers.cshtml) - Html - \n
TagHelper - (271:6,8 [39] BasicTagHelpers.cshtml) - input - TagMode.SelfClosing
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
SetTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (284:6,21 [8] BasicTagHelpers.cshtml)
IntermediateToken - (284:6,21 [8] BasicTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (284:6,21 [8] BasicTagHelpers.cshtml)
IntermediateToken - (284:6,21 [8] BasicTagHelpers.cshtml) - Html - checkbox
SetTagHelperProperty - (303:6,40 [4] BasicTagHelpers.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (303:6,40 [4] BasicTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (303:6,40 [4] BasicTagHelpers.cshtml) - CSharp - true
DefaultTagHelperExecute -
HtmlContent - (310:6,47 [6] BasicTagHelpers.cshtml)
IntermediateToken - (310:6,47 [6] BasicTagHelpers.cshtml) - Html - \n
CreateTagHelper - - TestNamespace.PTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - TestNamespace.PTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (114:3,14 [11] BasicTagHelpers.cshtml)
IntermediateToken - (114:3,14 [11] BasicTagHelpers.cshtml) - Html - Hello World
AddTagHelperHtmlAttribute - - data-delay - AttributeStructure.DoubleQuotes
DefaultTagHelperHtmlAttribute - - data-delay - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (139:3,39 [4] BasicTagHelpers.cshtml)
IntermediateToken - (139:3,39 [4] BasicTagHelpers.cshtml) - Html - 1000
DefaultTagHelperExecute -
HtmlContent - (320:7,8 [8] BasicTagHelpers.cshtml)
IntermediateToken - (320:7,8 [2] BasicTagHelpers.cshtml) - Html - \n
IntermediateToken - (322:8,0 [6] BasicTagHelpers.cshtml) - Html - </div>

View File

@ -1,15 +1,15 @@
Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
|"*, TestAssembly"|
Generated Location: (421:10,37 [17] )
Generated Location: (673:13,37 [17] )
|"*, TestAssembly"|
Source Location: (220:5,38 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
|ViewBag.DefaultInterval|
Generated Location: (1384:26,38 [23] )
Generated Location: (1363:26,38 [23] )
|ViewBag.DefaultInterval|
Source Location: (303:6,40 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
|true|
Generated Location: (2082:37,42 [4] )
Generated Location: (2061:37,42 [4] )
|true|

View File

@ -5,6 +5,9 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
#line hidden
public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_DesignTime
{
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
@ -18,9 +21,6 @@ global::System.Object __typeHelper = "*, TestAssembly";
}
#pragma warning restore 219
private static System.Object __o = null;
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper = null;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper = null;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2 = null;
#pragma warning disable 1998
public async System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,12 +1,15 @@
Document -
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_DesignTime - -
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
DesignTimeDirective -
DirectiveToken - (17:0,17 [5] BasicTagHelpers_Prefixed.cshtml) - "THS"
DirectiveToken - (38:1,14 [17] BasicTagHelpers_Prefixed.cshtml) - "*, TestAssembly"
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (22:0,22 [2] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (22:0,22 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
@ -17,7 +20,7 @@ Document -
IntermediateToken - (102:3,43 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
IntermediateToken - (103:3,44 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
TagHelper - (109:4,4 [136] BasicTagHelpers_Prefixed.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (135:4,30 [56] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (135:4,30 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
IntermediateToken - (145:5,8 [3] BasicTagHelpers_Prefixed.cshtml) - Html - <p>
@ -28,23 +31,25 @@ Document -
IntermediateToken - (180:6,26 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
IntermediateToken - (181:6,27 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
TagHelper - (191:7,8 [41] BasicTagHelpers_Prefixed.cshtml) - input - TagMode.StartTagOnly
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
SetTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
DefaultTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - Html - checkbox
SetTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - Type - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - Html - checkbox
SetTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - CSharp - true
DefaultTagHelperExecute -
HtmlContent - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
CreateTagHelper - - TestNamespace.PTagHelper
AddTagHelperHtmlAttribute - - class - AttributeStructure.DoubleQuotes
DefaultTagHelperCreate - - TestNamespace.PTagHelper
DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
HtmlContent - (122:4,17 [11] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (122:4,17 [11] BasicTagHelpers_Prefixed.cshtml) - Html - Hello World
DefaultTagHelperExecute -
HtmlContent - (245:8,11 [11] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (245:8,11 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
IntermediateToken - (247:9,0 [9] BasicTagHelpers_Prefixed.cshtml) - Html - </THSdiv>

View File

@ -1,15 +1,15 @@
Source Location: (17:0,17 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
|"THS"|
Generated Location: (430:10,37 [5] )
Generated Location: (682:13,37 [5] )
|"THS"|
Source Location: (38:1,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
|"*, TestAssembly"|
Generated Location: (535:14,37 [17] )
Generated Location: (787:17,37 [17] )
|"*, TestAssembly"|
Source Location: (226:7,43 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
|true|
Generated Location: (1569:31,43 [4] )
Generated Location: (1548:31,43 [4] )
|true|

View File

@ -10,9 +10,9 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
private string __tagHelperStringValueBuffer;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
@ -26,9 +26,9 @@ namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
return __backed__tagHelperScopeManager;
}
}
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper = null;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper = null;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2 = null;
private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
#pragma warning disable 1998
public async System.Threading.Tasks.Task ExecuteAsync()
{

View File

@ -1,9 +1,12 @@
Document -
NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_Runtime - -
DeclarePreallocatedTagHelperAttribute - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
DeclarePreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1 - class - Hello World - AttributeStructure.DoubleQuotes
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2
PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperRuntime -
FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (57:2,0 [52] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (57:2,0 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
@ -12,7 +15,7 @@ Document -
IntermediateToken - (102:3,43 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
IntermediateToken - (103:3,44 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
TagHelper - (109:4,4 [136] BasicTagHelpers_Prefixed.cshtml) - p - TagMode.StartTagAndEndTag
TagHelperBody -
DefaultTagHelperBody -
HtmlContent - (135:4,30 [56] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (135:4,30 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
IntermediateToken - (145:5,8 [3] BasicTagHelpers_Prefixed.cshtml) - Html - <p>
@ -23,17 +26,19 @@ Document -
IntermediateToken - (180:6,26 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
IntermediateToken - (181:6,27 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
TagHelper - (191:7,8 [41] BasicTagHelpers_Prefixed.cshtml) - input - TagMode.StartTagOnly
TagHelperBody -
CreateTagHelper - - TestNamespace.InputTagHelper
CreateTagHelper - - TestNamespace.InputTagHelper2
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_0 - type - Type
SetPreallocatedTagHelperProperty - - __tagHelperAttribute_0 - type - Type
SetTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - Checked - HtmlAttributeValueStyle.DoubleQuotes
DefaultTagHelperBody -
DefaultTagHelperCreate - - TestNamespace.InputTagHelper
DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
PreallocatedTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - __tagHelperAttribute_0 - type - Type
PreallocatedTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - __tagHelperAttribute_0 - type - Type
DefaultTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
IntermediateToken - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - CSharp - true
DefaultTagHelperExecute -
HtmlContent - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
CreateTagHelper - - TestNamespace.PTagHelper
AddPreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperCreate - - TestNamespace.PTagHelper
PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
DefaultTagHelperExecute -
HtmlContent - (245:8,11 [11] BasicTagHelpers_Prefixed.cshtml)
IntermediateToken - (245:8,11 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
IntermediateToken - (247:9,0 [9] BasicTagHelpers_Prefixed.cshtml) - Html - </THSdiv>

Some files were not shown because too many files have changed in this diff Show More