Finish writer implementation of the remaining IR nodes and added tests

- SetTagHelperPropertyIRNode
- ChecksumIRNode
- UsingStatementIRNode
- Preallocated attributes target extension
- HtmlAttributeIRNode and friends
- Design time directive helper target extension
- Removed renderers and rendering conventions
- Regenerated IR baselines
Issue - #846 and #1051
This commit is contained in:
Ajay Bhargav Baaskaran 2017-04-14 17:15:48 -07:00
parent 1696e2aebf
commit 4e2cd0c2d6
131 changed files with 3101 additions and 2309 deletions

View File

@ -7,6 +7,10 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public abstract class BasicWriter
{
public abstract void WriteChecksum(CSharpRenderingContext context, ChecksumIRNode node);
public abstract void WriteUsingStatement(CSharpRenderingContext context, UsingStatementIRNode node);
public abstract void WriteCSharpExpression(CSharpRenderingContext context, CSharpExpressionIRNode node);
public abstract void WriteCSharpStatement(CSharpRenderingContext context, CSharpStatementIRNode node);
@ -14,5 +18,9 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public abstract void WriteHtmlContent(CSharpRenderingContext context, HtmlContentIRNode node);
public abstract void WriteHtmlAttribute(CSharpRenderingContext context, HtmlAttributeIRNode node);
public abstract void WriteHtmlAttributeValue(CSharpRenderingContext context, HtmlAttributeValueIRNode node);
public abstract void WriteCSharpAttributeValue(CSharpRenderingContext context, CSharpAttributeValueIRNode node);
}
}

View File

@ -1,16 +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 Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class CSharpLiteralCodeConventions : CSharpRenderingConventions
{
public CSharpLiteralCodeConventions(CSharpCodeWriter writer) : base(writer)
{
}
public override string StartWriteMethod => StartWriteLiteralMethod;
}
}

View File

@ -1,28 +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 Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class CSharpRedirectRenderingConventions : CSharpRenderingConventions
{
public CSharpRedirectRenderingConventions(string redirectWriter, CSharpCodeWriter writer)
: base(writer)
{
RedirectWriter = redirectWriter;
}
public string RedirectWriter { get; }
public override string StartWriteMethod => "WriteTo(" + RedirectWriter + ", " /* ORIGINAL: WriteToMethodName */;
public override string StartWriteLiteralMethod => "WriteLiteralTo(" + RedirectWriter + ", " /* ORIGINAL: WriteLiteralToMethodName */;
public override string StartBeginWriteAttributeMethod => "BeginWriteAttributeTo(" + RedirectWriter + ", " /* ORIGINAL: BeginWriteAttributeToMethodName */;
public override string StartWriteAttributeValueMethod => "WriteAttributeValueTo(" + RedirectWriter + ", " /* ORIGINAL: WriteAttributeValueToMethodName */;
public override string StartEndWriteAttributeMethod => "EndWriteAttributeTo(" + RedirectWriter /* ORIGINAL: EndWriteAttributeToMethodName */;
}
}

View File

@ -10,8 +10,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class CSharpRenderingContext
{
private CSharpRenderingConventions _renderingConventions;
internal ICollection<DirectiveDescriptor> Directives { get; set; }
internal Func<string> IdGenerator { get; set; } = () => Guid.NewGuid().ToString("N");
@ -20,23 +18,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public CSharpCodeWriter Writer { get; set; }
internal CSharpRenderingConventions RenderingConventions
{
get
{
if (_renderingConventions == null)
{
_renderingConventions = new CSharpRenderingConventions(Writer);
}
return _renderingConventions;
}
set
{
_renderingConventions = value;
}
}
internal IList<RazorDiagnostic> Diagnostics { get; } = new List<RazorDiagnostic>();
internal RazorCodeDocument CodeDocument { get; set; }
@ -101,6 +82,18 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
return scope;
}
public TagHelperRenderingContextScope Push(TagHelperRenderingContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
var scope = new TagHelperRenderingContextScope(this, TagHelperRenderingContext);
TagHelperRenderingContext = context;
return scope;
}
public struct BasicWriterScope : IDisposable
{
private readonly CSharpRenderingContext _context;
@ -154,5 +147,27 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
_context.TagHelperWriter = _writer;
}
}
public struct TagHelperRenderingContextScope : IDisposable
{
private readonly CSharpRenderingContext _context;
private readonly TagHelperRenderingContext _renderingContext;
public TagHelperRenderingContextScope(CSharpRenderingContext context, TagHelperRenderingContext renderingContext)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
_context = context;
_renderingContext = renderingContext;
}
public void Dispose()
{
_context.TagHelperRenderingContext = _renderingContext;
}
}
}
}

View File

@ -1,27 +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 Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class CSharpRenderingConventions
{
public CSharpRenderingConventions(CSharpCodeWriter writer)
{
Writer = writer;
}
protected CSharpCodeWriter Writer { get; }
public virtual string StartWriteMethod => "Write(" /* ORIGINAL: WriteMethodName */;
public virtual string StartWriteLiteralMethod => "WriteLiteral(" /* ORIGINAL: WriteLiteralMethodName */;
public virtual string StartBeginWriteAttributeMethod => "BeginWriteAttribute(" /* ORIGINAL: BeginWriteAttributeMethodName */;
public virtual string StartWriteAttributeValueMethod => "WriteAttributeValue(" /* ORIGINAL: WriteAttributeValueMethodName */;
public virtual string StartEndWriteAttributeMethod => "EndWriteAttribute(" /* ORIGINAL: EndWriteAttributeMethodName */;
}
}

View File

@ -10,9 +10,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
private readonly CSharpRenderingContext _context;
private readonly RuntimeTarget _target;
private readonly PageStructureCSharpRenderer _renderer;
public DefaultDocumentWriter(RuntimeTarget target, CSharpRenderingContext context, PageStructureCSharpRenderer renderer)
public DefaultDocumentWriter(RuntimeTarget target, CSharpRenderingContext context)
{
if (target == null)
{
@ -24,14 +23,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
throw new ArgumentNullException(nameof(context));
}
if (renderer == null)
{
throw new ArgumentNullException(nameof(renderer));
}
_target = target;
_context = context;
_renderer = renderer;
}
public override void WriteDocument(DocumentIRNode node)
@ -41,7 +34,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
throw new ArgumentNullException(nameof(node));
}
var visitor = new Visitor(_target, _context, _renderer);
var visitor = new Visitor(_target, _context);
_context.RenderChildren = visitor.RenderChildren;
_context.RenderNode = visitor.Visit;
@ -56,13 +49,11 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
private readonly CSharpRenderingContext _context;
private readonly RuntimeTarget _target;
private readonly PageStructureCSharpRenderer _renderer;
public Visitor(RuntimeTarget target, CSharpRenderingContext context, PageStructureCSharpRenderer renderer)
public Visitor(RuntimeTarget target, CSharpRenderingContext context)
{
_target = target;
_context = context;
_renderer = renderer;
}
private CSharpRenderingContext Context => _context;
@ -81,6 +72,16 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
RenderChildren(node);
}
public override void VisitChecksum(ChecksumIRNode node)
{
Context.BasicWriter.WriteChecksum(Context, node);
}
public override void VisitUsingStatement(UsingStatementIRNode node)
{
Context.BasicWriter.WriteUsingStatement(Context, node);
}
public override void VisitNamespace(NamespaceDeclarationIRNode node)
{
Context.Writer
@ -188,6 +189,21 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Context.BasicWriter.WriteCSharpStatement(Context, node);
}
public override void VisitHtmlAttribute(HtmlAttributeIRNode node)
{
Context.BasicWriter.WriteHtmlAttribute(Context, node);
}
public override void VisitHtmlAttributeValue(HtmlAttributeValueIRNode node)
{
Context.BasicWriter.WriteHtmlAttributeValue(Context, node);
}
public override void VisitCSharpAttributeValue(CSharpAttributeValueIRNode node)
{
Context.BasicWriter.WriteCSharpAttributeValue(Context, node);
}
public override void VisitHtml(HtmlContentIRNode node)
{
Context.BasicWriter.WriteHtmlContent(Context, node);
@ -200,10 +216,10 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override void VisitTagHelper(TagHelperIRNode node)
{
var initialRenderingContext = Context.TagHelperRenderingContext;
Context.TagHelperRenderingContext = new TagHelperRenderingContext();
Context.RenderChildren(node);
Context.TagHelperRenderingContext = initialRenderingContext;
using (Context.Push(new TagHelperRenderingContext()))
{
Context.RenderChildren(node);
}
}
public override void VisitInitializeTagHelperStructure(InitializeTagHelperStructureIRNode node)
@ -221,6 +237,11 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Context.TagHelperWriter.WriteAddTagHelperHtmlAttribute(Context, node);
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
{
Context.TagHelperWriter.WriteSetTagHelperProperty(Context, node);
}
public override void VisitExecuteTagHelpers(ExecuteTagHelpersIRNode node)
{
Context.TagHelperWriter.WriteExecuteTagHelpers(Context, node);
@ -228,9 +249,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override void VisitDefault(RazorIRNode node)
{
// This is a temporary bridge to the renderer, which allows us to move functionality piecemeal
// into this class.
_renderer.Visit(node);
Context.RenderChildren(node);
}
}
}

View File

@ -21,17 +21,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override DocumentWriter CreateWriter(CSharpRenderingContext context)
{
PageStructureCSharpRenderer renderer;
if (_options.DesignTimeMode)
{
renderer = new DesignTimeCSharpRenderer(this, context);
}
else
{
renderer = new RuntimeCSharpRenderer(this, context);
}
return new DefaultDocumentWriter(this, context, renderer);
return new DefaultDocumentWriter(this, context);
}
public override TExtension GetExtension<TExtension>()

View File

@ -8,6 +8,27 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class DesignTimeBasicWriter : BasicWriter
{
public override void WriteChecksum(CSharpRenderingContext context, ChecksumIRNode node)
{
// Do nothing
}
public override void WriteUsingStatement(CSharpRenderingContext context, UsingStatementIRNode node)
{
if (node.Source.HasValue)
{
using (context.Writer.BuildLinePragma(node.Source.Value))
{
context.AddLineMappingFor(node);
context.Writer.WriteUsing(node.Content);
}
}
else
{
context.Writer.WriteUsing(node.Content);
}
}
public override void WriteCSharpExpression(CSharpRenderingContext context, CSharpExpressionIRNode node)
{
if (context == null)
@ -124,7 +145,17 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override void WriteHtmlAttribute(CSharpRenderingContext context, HtmlAttributeIRNode node)
{
throw new NotImplementedException();
context.RenderChildren(node);
}
public override void WriteHtmlAttributeValue(CSharpRenderingContext context, HtmlAttributeValueIRNode node)
{
context.RenderChildren(node);
}
public override void WriteCSharpAttributeValue(CSharpRenderingContext context, CSharpAttributeValueIRNode node)
{
context.RenderChildren(node);
}
public override void WriteHtmlContent(CSharpRenderingContext context, HtmlContentIRNode node)

View File

@ -1,373 +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.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class DesignTimeCSharpRenderer : PageStructureCSharpRenderer
{
public DesignTimeCSharpRenderer(RuntimeTarget target, CSharpRenderingContext context)
: base(target, context)
{
}
public override void VisitCSharpExpression(CSharpExpressionIRNode node)
{
// We can't remove this yet, because it's still used recursively in a few places.
if (node.Children.Count == 0)
{
return;
}
if (node.Source != null)
{
using (Context.Writer.BuildLinePragma(node.Source.Value))
{
var offset = RazorDesignTimeIRPass.DesignTimeVariable.Length + " = ".Length;
var padding = BuildOffsetPadding(offset, node.Source.Value, Context);
Context.Writer
.Write(padding)
.WriteStartAssignment(RazorDesignTimeIRPass.DesignTimeVariable);
for (var i = 0; i < node.Children.Count; i++)
{
var token = node.Children[i] as RazorIRToken;
if (token != null && token.IsCSharp)
{
Context.AddLineMappingFor(token);
Context.Writer.Write(token.Content);
}
else
{
// There may be something else inside the expression like a Template or another extension node.
Visit(node.Children[i]);
}
}
Context.Writer.WriteLine(";");
}
}
else
{
Context.Writer.WriteStartAssignment(RazorDesignTimeIRPass.DesignTimeVariable);
VisitDefault(node);
Context.Writer.WriteLine(";");
}
}
public override void VisitUsingStatement(UsingStatementIRNode node)
{
if (node.Source.HasValue)
{
using (Context.Writer.BuildLinePragma(node.Source.Value))
{
Context.AddLineMappingFor(node);
Context.Writer.WriteUsing(node.Content);
}
}
else
{
Context.Writer.WriteUsing(node.Content);
}
}
public override void VisitCSharpStatement(CSharpStatementIRNode node)
{
// We can't remove this yet, because it's still used recursively in a few places.
var isWhitespaceStatement = true;
for (var i = 0; i < node.Children.Count; i++)
{
var token = node.Children[i] as RazorIRToken;
if (token == null || !string.IsNullOrWhiteSpace(token.Content))
{
isWhitespaceStatement = false;
break;
}
}
IDisposable linePragmaScope = null;
if (node.Source != null)
{
if (!isWhitespaceStatement)
{
linePragmaScope = Context.Writer.BuildLinePragma(node.Source.Value);
}
var padding = BuildOffsetPadding(0, node.Source.Value, Context);
Context.Writer.Write(padding);
}
else if (isWhitespaceStatement)
{
// Don't write whitespace if there is no line mapping for it.
return;
}
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken token && token.IsCSharp)
{
Context.AddLineMappingFor(token);
Context.Writer.Write(token.Content);
}
else
{
// There may be something else inside the statement like an extension node.
Visit(node.Children[i]);
}
}
if (linePragmaScope != null)
{
linePragmaScope.Dispose();
}
else
{
Context.Writer.WriteLine();
}
}
public override void VisitDirectiveToken(DirectiveTokenIRNode node)
{
const string TypeHelper = "__typeHelper";
var tokenKind = node.Descriptor.Kind;
if (!node.Source.HasValue ||
!string.Equals(
Context.SourceDocument.FileName,
node.Source.Value.FilePath,
StringComparison.OrdinalIgnoreCase))
{
// We don't want to handle directives from imports.
return;
}
// Wrap the directive token in a lambda to isolate variable names.
Context.Writer
.Write("((")
.Write(typeof(Action).FullName)
.Write(")(");
using (Context.Writer.BuildLambda(endLine: false))
{
var originalIndent = Context.Writer.CurrentIndent;
Context.Writer.ResetIndent();
switch (tokenKind)
{
case DirectiveTokenKind.Type:
// {node.Content} __typeHelper = null;
Context.AddLineMappingFor(node);
Context.Writer
.Write(node.Content)
.Write(" ")
.WriteStartAssignment(TypeHelper)
.WriteLine("null;");
break;
case DirectiveTokenKind.Member:
// global::System.Object {node.content} = null;
Context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ");
Context.AddLineMappingFor(node);
Context.Writer
.Write(node.Content)
.WriteLine(" = null;");
break;
case DirectiveTokenKind.Namespace:
// global::System.Object __typeHelper = nameof({node.Content});
Context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
Context.Writer.Write("nameof(");
Context.AddLineMappingFor(node);
Context.Writer
.Write(node.Content)
.WriteLine(");");
break;
case DirectiveTokenKind.String:
// global::System.Object __typeHelper = "{node.Content}";
Context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
if (node.Content.StartsWith("\"", StringComparison.Ordinal))
{
Context.AddLineMappingFor(node);
Context.Writer.Write(node.Content);
}
else
{
Context.Writer.Write("\"");
Context.AddLineMappingFor(node);
Context.Writer
.Write(node.Content)
.Write("\"");
}
Context.Writer.WriteLine(";");
break;
}
Context.Writer.SetIndent(originalIndent);
}
Context.Writer.WriteLine("))();");
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode 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.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty))
{
VisitDefault(node);
Context.Writer.WriteStartAssignment(propertyValueAccessor);
if (node.Children.Count == 1 && node.Children.First() is HtmlContentIRNode htmlNode)
{
var content = GetContent(htmlNode);
Context.Writer.WriteStringLiteral(content);
}
else
{
Context.Writer.Write("string.Empty");
}
Context.Writer.WriteLine(";");
}
else
{
var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as RazorIRNode;
var valueStart = firstMappedChild?.Source;
using (Context.Writer.BuildLinePragma(node.Source.Value))
{
var assignmentPrefixLength = propertyValueAccessor.Length + " = ".Length;
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is HtmlContentIRNode)
{
assignmentPrefixLength += $"global::{node.Descriptor.TypeName}.".Length;
if (valueStart != null)
{
var padding = BuildOffsetPadding(assignmentPrefixLength, node.Source.Value, Context);
Context.Writer.Write(padding);
}
Context.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
else
{
if (valueStart != null)
{
var padding = BuildOffsetPadding(assignmentPrefixLength, node.Source.Value, Context);
Context.Writer.Write(padding);
}
Context.Writer.WriteStartAssignment(propertyValueAccessor);
}
RenderTagHelperAttributeInline(node, node.Source.Value);
Context.Writer.WriteLine(";");
}
}
}
private void RenderTagHelperAttributeInline(
RazorIRNode node,
SourceSpan documentLocation)
{
if (node is SetTagHelperPropertyIRNode || node is CSharpExpressionIRNode || node is HtmlContentIRNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(node.Children[i], documentLocation);
}
}
else if (node is RazorIRToken token)
{
if (node.Source != null)
{
Context.AddLineMappingFor(node);
}
Context.Writer.Write(token.Content);
}
else if (node is CSharpStatementIRNode)
{
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 TemplateIRNode)
{
var attributeValueNode = (SetTagHelperPropertyIRNode)node.Parent;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(attributeValueNode.Descriptor.TypeName),
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
Context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
}
private string GetContent(HtmlContentIRNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken token && token.IsHtml)
{
builder.Append(token.Content);
}
}
return builder.ToString();
}
}
}

View File

@ -0,0 +1,134 @@
// 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.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class DesignTimeDirectiveTargetExtension : IDesignTimeDirectiveTargetExtension
{
private const string DirectiveTokenHelperMethodName = "__RazorDirectiveTokenHelpers__";
private const string TypeHelper = "__typeHelper";
public void WriteDesignTimeDirective(CSharpRenderingContext context, DesignTimeDirectiveIRNode node)
{
context.Writer
.WritePragma("warning disable 219")
.WriteLine($"private void {DirectiveTokenHelperMethodName}() {{");
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is DirectiveTokenIRNode n)
{
WriteDesignTimeDirectiveToken(context, n);
}
}
context.Writer
.WriteLine("}")
.WritePragma("warning restore 219");
}
private void WriteDesignTimeDirectiveToken(CSharpRenderingContext context, DirectiveTokenIRNode node)
{
var tokenKind = node.Descriptor.Kind;
if (!node.Source.HasValue ||
!string.Equals(
context.SourceDocument?.FileName,
node.Source.Value.FilePath,
StringComparison.OrdinalIgnoreCase))
{
// We don't want to handle directives from imports.
return;
}
// Wrap the directive token in a lambda to isolate variable names.
context.Writer
.Write("((")
.Write(typeof(Action).FullName)
.Write(")(");
using (context.Writer.BuildLambda(endLine: false))
{
var originalIndent = context.Writer.CurrentIndent;
context.Writer.ResetIndent();
switch (tokenKind)
{
case DirectiveTokenKind.Type:
// {node.Content} __typeHelper = null;
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.Write(" ")
.WriteStartAssignment(TypeHelper)
.WriteLine("null;");
break;
case DirectiveTokenKind.Member:
// global::System.Object {node.content} = null;
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.WriteLine(" = null;");
break;
case DirectiveTokenKind.Namespace:
// global::System.Object __typeHelper = nameof({node.Content});
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
context.Writer.Write("nameof(");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.WriteLine(");");
break;
case DirectiveTokenKind.String:
// global::System.Object __typeHelper = "{node.Content}";
context.Writer
.Write("global::")
.Write(typeof(object).FullName)
.Write(" ")
.WriteStartAssignment(TypeHelper);
if (node.Content.StartsWith("\"", StringComparison.Ordinal))
{
context.AddLineMappingFor(node);
context.Writer.Write(node.Content);
}
else
{
context.Writer.Write("\"");
context.AddLineMappingFor(node);
context.Writer
.Write(node.Content)
.Write("\"");
}
context.Writer.WriteLine(";");
break;
}
context.Writer.SetIndent(originalIndent);
}
context.Writer.WriteLine("))();");
}
}
}

View File

@ -2,7 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
@ -53,9 +56,153 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override void WriteSetTagHelperProperty(CSharpRenderingContext context, SetTagHelperPropertyIRNode node)
{
throw new NotImplementedException();
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.Writer
.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.Writer.WriteStartAssignment(propertyValueAccessor);
if (node.Children.Count == 1 && node.Children.First() is HtmlContentIRNode htmlNode)
{
var content = GetContent(htmlNode);
context.Writer.WriteStringLiteral(content);
}
else
{
context.Writer.Write("string.Empty");
}
context.Writer.WriteLine(";");
}
else
{
var firstMappedChild = node.Children.FirstOrDefault(child => child.Source != null) as RazorIRNode;
var valueStart = firstMappedChild?.Source;
using (context.Writer.BuildLinePragma(node.Source.Value))
{
var assignmentPrefixLength = propertyValueAccessor.Length + " = ".Length;
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is HtmlContentIRNode)
{
assignmentPrefixLength += $"global::{node.Descriptor.TypeName}.".Length;
if (valueStart != null)
{
context.Writer.WritePadding(assignmentPrefixLength, node.Source.Value, context);
}
context.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
else
{
if (valueStart != null)
{
context.Writer.WritePadding(assignmentPrefixLength, node.Source.Value, context);
}
context.Writer.WriteStartAssignment(propertyValueAccessor);
}
RenderTagHelperAttributeInline(context, node, node.Source.Value);
context.Writer.WriteLine(";");
}
}
}
private void RenderTagHelperAttributeInline(
CSharpRenderingContext context,
RazorIRNode node,
SourceSpan documentLocation)
{
if (node is SetTagHelperPropertyIRNode || node is CSharpExpressionIRNode || node is HtmlContentIRNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, node.Children[i], documentLocation);
}
}
else if (node is RazorIRToken token)
{
if (node.Source != null)
{
context.AddLineMappingFor(node);
}
context.Writer.Write(token.Content);
}
else if (node is CSharpStatementIRNode)
{
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 TemplateIRNode)
{
var attributeValueNode = (SetTagHelperPropertyIRNode)node.Parent;
var error = new RazorError(
LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(attributeValueNode.Descriptor.TypeName),
new SourceLocation(documentLocation.AbsoluteIndex, documentLocation.CharacterIndex, documentLocation.Length),
documentLocation.Length);
context.Diagnostics.Add(RazorDiagnostic.Create(error));
}
}
private string GetContent(HtmlContentIRNode node)
{
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken 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.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
}
}

View File

@ -0,0 +1,12 @@
// 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.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal interface IDesignTimeDirectiveTargetExtension : IRuntimeTargetExtension
{
void WriteDesignTimeDirective(CSharpRenderingContext context, DesignTimeDirectiveIRNode node);
}
}

View File

@ -0,0 +1,18 @@
// 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.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal interface IPreallocatedAttributeTargetExtension : IRuntimeTargetExtension
{
void WriteDeclarePreallocatedTagHelperHtmlAttribute(CSharpRenderingContext context, DeclarePreallocatedTagHelperHtmlAttributeIRNode node);
void WriteAddPreallocatedTagHelperHtmlAttribute(CSharpRenderingContext context, AddPreallocatedTagHelperHtmlAttributeIRNode node);
void WriteDeclarePreallocatedTagHelperAttribute(CSharpRenderingContext context, DeclarePreallocatedTagHelperAttributeIRNode node);
void WriteSetPreallocatedTagHelperProperty(CSharpRenderingContext context, SetPreallocatedTagHelperPropertyIRNode node);
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class LiteralRuntimeBasicWriter : RuntimeBasicWriter
{
public override string WriteCSharpExpressionMethod { get; set; } = "WriteLiteral";
}
}

View File

@ -1,102 +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 Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class PageStructureCSharpRenderer : RazorIRNodeWalker
{
protected readonly CSharpRenderingContext Context;
protected readonly RuntimeTarget Target;
public PageStructureCSharpRenderer(RuntimeTarget target, CSharpRenderingContext context)
{
Context = context;
Target = target;
}
public override void VisitExtension(ExtensionIRNode node)
{
// This needs to stay here until the rest of the code in the renderers is rewritten because
// and extension can occur at any level.
node.WriteNode(Target, Context);
}
protected static void RenderExpressionInline(RazorIRNode node, CSharpRenderingContext context)
{
if (node is RazorIRToken token && token.IsCSharp)
{
context.Writer.Write(token.Content);
}
else
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderExpressionInline(node.Children[i], context);
}
}
}
protected static int CalculateExpressionPadding(SourceSpan sourceRange, CSharpRenderingContext context)
{
var spaceCount = 0;
for (var i = sourceRange.AbsoluteIndex - 1; i >= 0; i--)
{
var @char = context.SourceDocument[i];
if (@char == '\n' || @char == '\r')
{
break;
}
else if (@char == '\t')
{
spaceCount += context.Options.TabSize;
}
else
{
spaceCount++;
}
}
return spaceCount;
}
protected static string BuildOffsetPadding(int generatedOffset, SourceSpan sourceRange, CSharpRenderingContext context)
{
var basePadding = CalculateExpressionPadding(sourceRange, context);
var resolvedPadding = Math.Max(basePadding - generatedOffset, 0);
if (context.Options.IsIndentingWithTabs)
{
var spaces = resolvedPadding % context.Options.TabSize;
var tabs = resolvedPadding / context.Options.TabSize;
return new string('\t', tabs) + new string(' ', spaces);
}
else
{
return new string(' ', resolvedPadding);
}
}
protected static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
protected static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,
string attributeName,
BoundAttributeDescriptor descriptor)
{
var propertyAccessor = $"{tagHelperVariableName}.{descriptor.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
}
}

View File

@ -0,0 +1,108 @@
// 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.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class PreallocatedAttributeTargetExtension : IPreallocatedAttributeTargetExtension
{
public string TagHelperAttributeTypeName { get; set; } = "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute";
public string EncodedHtmlStringTypeName { get; set; } = "Microsoft.AspNetCore.Html.HtmlString";
public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext";
public string ExecutionContextAddHtmlAttributeMethodName { get; set; } = "AddHtmlAttribute";
public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute";
public void WriteDeclarePreallocatedTagHelperHtmlAttribute(CSharpRenderingContext context, DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
{
context.Writer
.Write("private static readonly global::")
.Write(TagHelperAttributeTypeName)
.Write(" ")
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + TagHelperAttributeTypeName)
.WriteStringLiteral(node.Name);
if (node.ValueStyle == HtmlAttributeValueStyle.Minimized)
{
context.Writer.WriteEndMethodInvocation();
}
else
{
context.Writer
.WriteParameterSeparator()
.WriteStartNewObject("global::" + EncodedHtmlStringTypeName)
.WriteStringLiteral(node.Value)
.WriteEndMethodInvocation(endLine: false)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
}
public void WriteAddPreallocatedTagHelperHtmlAttribute(CSharpRenderingContext context, AddPreallocatedTagHelperHtmlAttributeIRNode node)
{
context.Writer
.WriteStartInstanceMethodInvocation(ExecutionContextVariableName, ExecutionContextAddHtmlAttributeMethodName)
.Write(node.VariableName)
.WriteEndMethodInvocation();
}
public void WriteDeclarePreallocatedTagHelperAttribute(CSharpRenderingContext context, DeclarePreallocatedTagHelperAttributeIRNode node)
{
context.Writer
.Write("private static readonly global::")
.Write(TagHelperAttributeTypeName)
.Write(" ")
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + TagHelperAttributeTypeName)
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStringLiteral(node.Value)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
public void WriteSetPreallocatedTagHelperProperty(CSharpRenderingContext context, SetPreallocatedTagHelperPropertyIRNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
var attributeValueAccessor = $"{node.VariableName}.Value" /* ORIGINAL: TagHelperAttributeValuePropertyName */;
context.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write("(string)")
.Write(attributeValueAccessor)
.WriteLine(";")
.WriteStartInstanceMethodInvocation(ExecutionContextVariableName, ExecutionContextAddTagHelperAttributeMethodName)
.Write(node.VariableName)
.WriteEndMethodInvocation();
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
private static string GetTagHelperPropertyAccessor(
bool isIndexerNameMatch,
string tagHelperVariableName,
string attributeName,
BoundAttributeDescriptor descriptor)
{
var propertyAccessor = $"{tagHelperVariableName}.{descriptor.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
}
}

View File

@ -2,6 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -16,9 +19,15 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
_textWriter = textWriter;
}
public new string WriteCSharpExpressionMethod { get; set; } = "WriteTo";
public override string WriteCSharpExpressionMethod { get; set; } = "WriteTo";
public new string WriteHtmlContentMethod { get; set; } = "WriteLiteralTo";
public override string WriteHtmlContentMethod { get; set; } = "WriteLiteralTo";
public override string BeginWriteAttributeMethod { get; set; } = "BeginWriteAttributeTo";
public override string EndWriteAttributeMethod { get; set; } = "EndWriteAttributeTo";
public override string WriteAttributeValueMethod { get; set; } = "WriteAttributeValueTo";
public override void WriteCSharpExpression(CSharpRenderingContext context, CSharpExpressionIRNode node)
{
@ -92,7 +101,112 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
.WriteEndMethodInvocation();
charactersConsumed += textToRender.Length;
}
}
}
public override void WriteHtmlAttribute(CSharpRenderingContext context, HtmlAttributeIRNode node)
{
var valuePieceCount = node
.Children
.Count(child => child is HtmlAttributeValueIRNode || child is CSharpAttributeValueIRNode);
var prefixLocation = node.Source.Value.AbsoluteIndex;
var suffixLocation = node.Source.Value.AbsoluteIndex + node.Source.Value.Length - node.Suffix.Length;
context.Writer
.WriteStartMethodInvocation(BeginWriteAttributeMethod)
.Write(_textWriter)
.WriteParameterSeparator()
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Suffix)
.WriteParameterSeparator()
.Write(suffixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
.WriteEndMethodInvocation();
context.RenderChildren(node);
context.Writer
.WriteStartMethodInvocation(EndWriteAttributeMethod)
.Write(_textWriter)
.WriteEndMethodInvocation();
}
public override void WriteHtmlAttributeValue(CSharpRenderingContext context, HtmlAttributeValueIRNode node)
{
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length;
context.Writer
.WriteStartMethodInvocation(WriteAttributeValueMethod)
.Write(_textWriter)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Content)
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(true)
.WriteEndMethodInvocation();
}
public override void WriteCSharpAttributeValue(CSharpRenderingContext context, CSharpAttributeValueIRNode node)
{
const string ValueWriterName = "__razor_attribute_value_writer";
var expressionValue = node.Children.FirstOrDefault() as CSharpExpressionIRNode;
var linePragma = expressionValue != null ? context.Writer.BuildLinePragma(node.Source.Value) : null;
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length - node.Prefix.Length;
context.Writer
.WriteStartMethodInvocation(WriteAttributeValueMethod)
.Write(_textWriter)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator();
if (expressionValue != null)
{
Debug.Assert(node.Children.Count == 1);
RenderExpressionInline(context, expressionValue);
}
else
{
// Not an expression; need to buffer the result.
context.Writer.WriteStartNewObject(TemplateTypeName);
using (context.Push(new RedirectedRuntimeBasicWriter(ValueWriterName)))
using (context.Writer.BuildAsyncLambda(endLine: false, parameterNames: ValueWriterName))
{
context.RenderChildren(node);
}
context.Writer.WriteEndMethodInvocation(false);
}
context.Writer
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(false)
.WriteEndMethodInvocation();
linePragma?.Dispose();
}
}
}

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
_textWriter = textWriter;
}
public new string WriteTagHelperOutputMethod { get; set; } = "WriteTo";
public override string WriteTagHelperOutputMethod { get; set; } = "WriteTo";
public override void WriteExecuteTagHelpers(CSharpRenderingContext context, ExecuteTagHelpersIRNode node)
{

View File

@ -2,6 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
@ -9,11 +12,47 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class RuntimeBasicWriter : BasicWriter
{
public string WriteCSharpExpressionMethod { get; set; } = "Write";
public virtual string WriteCSharpExpressionMethod { get; set; } = "Write";
public string WriteHtmlContentMethod { get; set; } = "WriteLiteral";
public virtual string WriteHtmlContentMethod { get; set; } = "WriteLiteral";
public string WriteAttributeValueMethod { get; set; } = "WriteAttributeValue";
public virtual string BeginWriteAttributeMethod { get; set; } = "BeginWriteAttribute";
public virtual string EndWriteAttributeMethod { get; set; } = "EndWriteAttribute";
public virtual string WriteAttributeValueMethod { get; set; } = "WriteAttributeValue";
public string TemplateTypeName { get; set; } = "Microsoft.AspNetCore.Mvc.Razor.HelperResult";
public override void WriteChecksum(CSharpRenderingContext context, ChecksumIRNode node)
{
if (!string.IsNullOrEmpty(node.Bytes))
{
context.Writer
.Write("#pragma checksum \"")
.Write(node.FileName)
.Write("\" \"")
.Write(node.Guid)
.Write("\" \"")
.Write(node.Bytes)
.WriteLine("\"");
}
}
public override void WriteUsingStatement(CSharpRenderingContext context, UsingStatementIRNode node)
{
if (node.Source.HasValue)
{
using (context.Writer.BuildLinePragma(node.Source.Value))
{
context.Writer.WriteUsing(node.Content);
}
}
else
{
context.Writer.WriteUsing(node.Content);
}
}
public override void WriteCSharpExpression(CSharpRenderingContext context, CSharpExpressionIRNode node)
{
@ -102,7 +141,100 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public override void WriteHtmlAttribute(CSharpRenderingContext context, HtmlAttributeIRNode node)
{
throw new NotImplementedException();
var valuePieceCount = node
.Children
.Count(child => child is HtmlAttributeValueIRNode || child is CSharpAttributeValueIRNode);
var prefixLocation = node.Source.Value.AbsoluteIndex;
var suffixLocation = node.Source.Value.AbsoluteIndex + node.Source.Value.Length - node.Suffix.Length;
context.Writer
.WriteStartMethodInvocation(BeginWriteAttributeMethod)
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Suffix)
.WriteParameterSeparator()
.Write(suffixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
.WriteEndMethodInvocation();
context.RenderChildren(node);
context.Writer
.WriteStartMethodInvocation(EndWriteAttributeMethod)
.WriteEndMethodInvocation();
}
public override void WriteHtmlAttributeValue(CSharpRenderingContext context, HtmlAttributeValueIRNode node)
{
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length;
context.Writer
.WriteStartMethodInvocation(WriteAttributeValueMethod)
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Content)
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(true)
.WriteEndMethodInvocation();
}
public override void WriteCSharpAttributeValue(CSharpRenderingContext context, CSharpAttributeValueIRNode node)
{
const string ValueWriterName = "__razor_attribute_value_writer";
var expressionValue = node.Children.FirstOrDefault() as CSharpExpressionIRNode;
var linePragma = expressionValue != null ? context.Writer.BuildLinePragma(node.Source.Value) : null;
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length - node.Prefix.Length;
context.Writer
.WriteStartMethodInvocation(WriteAttributeValueMethod)
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator();
if (expressionValue != null)
{
Debug.Assert(node.Children.Count == 1);
RenderExpressionInline(context, expressionValue);
}
else
{
// Not an expression; need to buffer the result.
context.Writer.WriteStartNewObject(TemplateTypeName);
using (context.Push(new RedirectedRuntimeBasicWriter(ValueWriterName)))
using (context.Writer.BuildAsyncLambda(endLine: false, parameterNames: ValueWriterName))
{
context.RenderChildren(node);
}
context.Writer.WriteEndMethodInvocation(false);
}
context.Writer
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(false)
.WriteEndMethodInvocation();
linePragma?.Dispose();
}
public override void WriteHtmlContent(CSharpRenderingContext context, HtmlContentIRNode node)
@ -144,5 +276,20 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
charactersConsumed += textToRender.Length;
}
}
protected static void RenderExpressionInline(CSharpRenderingContext context, RazorIRNode node)
{
if (node is RazorIRToken token && token.IsCSharp)
{
context.Writer.Write(token.Content);
}
else
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderExpressionInline(context, node.Children[i]);
}
}
}
}
}

View File

@ -1,483 +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.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class RuntimeCSharpRenderer : PageStructureCSharpRenderer
{
public RuntimeCSharpRenderer(RuntimeTarget target, CSharpRenderingContext context)
: base(target, context)
{
}
public override void VisitChecksum(ChecksumIRNode node)
{
if (!string.IsNullOrEmpty(node.Bytes))
{
Context.Writer
.Write("#pragma checksum \"")
.Write(node.FileName)
.Write("\" \"")
.Write(node.Guid)
.Write("\" \"")
.Write(node.Bytes)
.WriteLine("\"");
}
}
public override void VisitHtml(HtmlContentIRNode node)
{
// We can't remove this yet, because it's still used recursively in a few places.
const int MaxStringLiteralLength = 1024;
var builder = new StringBuilder();
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken token && token.IsHtml)
{
builder.Append(token.Content);
}
}
var content = builder.ToString();
var charactersConsumed = 0;
// Render the string in pieces to avoid Roslyn OOM exceptions at compile time: https://github.com/aspnet/External/issues/54
while (charactersConsumed < content.Length)
{
string textToRender;
if (content.Length <= MaxStringLiteralLength)
{
textToRender = content;
}
else
{
var charactersToSubstring = Math.Min(MaxStringLiteralLength, content.Length - charactersConsumed);
textToRender = content.Substring(charactersConsumed, charactersToSubstring);
}
Context.Writer
.Write(Context.RenderingConventions.StartWriteLiteralMethod)
.WriteStringLiteral(textToRender)
.WriteEndMethodInvocation();
charactersConsumed += textToRender.Length;
}
}
public override void VisitCSharpExpression(CSharpExpressionIRNode node)
{
// We can't remove this yet, because it's still used recursively in a few places.
IDisposable linePragmaScope = null;
if (node.Source != null)
{
linePragmaScope = Context.Writer.BuildLinePragma(node.Source.Value);
var padding = BuildOffsetPadding(Context.RenderingConventions.StartWriteMethod.Length, node.Source.Value, Context);
Context.Writer.Write(padding);
}
Context.Writer.Write(Context.RenderingConventions.StartWriteMethod);
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken token && token.IsCSharp)
{
Context.Writer.Write(token.Content);
}
else
{
// There may be something else inside the expression like a Template or another extension node.
Visit(node.Children[i]);
}
}
Context.Writer.WriteEndMethodInvocation();
linePragmaScope?.Dispose();
}
public override void VisitUsingStatement(UsingStatementIRNode node)
{
if (node.Source.HasValue)
{
using (Context.Writer.BuildLinePragma(node.Source.Value))
{
Context.Writer.WriteUsing(node.Content);
}
}
else
{
Context.Writer.WriteUsing(node.Content);
}
}
public override void VisitHtmlAttribute(HtmlAttributeIRNode node)
{
var valuePieceCount = node
.Children
.Count(child => child is HtmlAttributeValueIRNode || child is CSharpAttributeValueIRNode);
var prefixLocation = node.Source.Value.AbsoluteIndex;
var suffixLocation = node.Source.Value.AbsoluteIndex + node.Source.Value.Length - node.Suffix.Length;
Context.Writer
.Write(Context.RenderingConventions.StartBeginWriteAttributeMethod)
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Suffix)
.WriteParameterSeparator()
.Write(suffixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valuePieceCount.ToString(CultureInfo.InvariantCulture))
.WriteEndMethodInvocation();
VisitDefault(node);
Context.Writer
.Write(Context.RenderingConventions.StartEndWriteAttributeMethod)
.WriteEndMethodInvocation();
}
public override void VisitHtmlAttributeValue(HtmlAttributeValueIRNode node)
{
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length;
Context.Writer
.Write(Context.RenderingConventions.StartWriteAttributeValueMethod)
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteStringLiteral(node.Content)
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(true)
.WriteEndMethodInvocation();
}
public override void VisitCSharpAttributeValue(CSharpAttributeValueIRNode node)
{
const string ValueWriterName = "__razor_attribute_value_writer";
var expressionValue = node.Children.FirstOrDefault() as CSharpExpressionIRNode;
var linePragma = expressionValue != null ? Context.Writer.BuildLinePragma(node.Source.Value) : null;
var prefixLocation = node.Source.Value.AbsoluteIndex;
var valueLocation = node.Source.Value.AbsoluteIndex + node.Prefix.Length;
var valueLength = node.Source.Value.Length - node.Prefix.Length;
Context.Writer
.Write(Context.RenderingConventions.StartWriteAttributeValueMethod)
.WriteStringLiteral(node.Prefix)
.WriteParameterSeparator()
.Write(prefixLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator();
if (expressionValue != null)
{
Debug.Assert(node.Children.Count == 1);
RenderExpressionInline(expressionValue, Context);
}
else
{
// Not an expression; need to buffer the result.
Context.Writer.WriteStartNewObject("Microsoft.AspNetCore.Mvc.Razor.HelperResult" /* ORIGINAL: TemplateTypeName */);
var initialRenderingConventions = Context.RenderingConventions;
Context.RenderingConventions = new CSharpRedirectRenderingConventions(ValueWriterName, Context.Writer);
using (Context.Writer.BuildAsyncLambda(endLine: false, parameterNames: ValueWriterName))
{
VisitDefault(node);
}
Context.RenderingConventions = initialRenderingConventions;
Context.Writer.WriteEndMethodInvocation(false);
}
Context.Writer
.WriteParameterSeparator()
.Write(valueLocation.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.Write(valueLength.ToString(CultureInfo.InvariantCulture))
.WriteParameterSeparator()
.WriteBooleanLiteral(false)
.WriteEndMethodInvocation();
linePragma?.Dispose();
}
public override void VisitCSharpStatement(CSharpStatementIRNode node)
{
// We can't remove this yet, because it's still used recursively in a few places.
var isWhitespaceStatement = true;
for (var i = 0; i < node.Children.Count; i++)
{
var token = node.Children[i] as RazorIRToken;
if (token == null || !string.IsNullOrWhiteSpace(token.Content))
{
isWhitespaceStatement = false;
break;
}
}
if (isWhitespaceStatement)
{
return;
}
IDisposable linePragmaScope = null;
if (node.Source != null)
{
linePragmaScope = Context.Writer.BuildLinePragma(node.Source.Value);
var padding = BuildOffsetPadding(0, node.Source.Value, Context);
Context.Writer.Write(padding);
}
for (var i = 0; i < node.Children.Count; i++)
{
if (node.Children[i] is RazorIRToken token && token.IsCSharp)
{
Context.Writer.Write(token.Content);
}
else
{
// There may be something else inside the statement like an extension node.
Visit(node.Children[i]);
}
}
if (linePragmaScope == null)
{
Context.Writer.WriteLine();
}
linePragmaScope?.Dispose();
}
public override void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
{
Context.Writer
.WriteStartInstanceMethodInvocation(
"__tagHelperExecutionContext" /* ORIGINAL: ExecutionContextVariableName */,
"AddHtmlAttribute" /* ORIGINAL: ExecutionContextAddHtmlAttributeMethodName */)
.Write(node.VariableName)
.WriteEndMethodInvocation();
}
public override void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
var attributeValueAccessor = $"{node.VariableName}.Value" /* ORIGINAL: TagHelperAttributeValuePropertyName */;
Context.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write("(string)")
.Write(attributeValueAccessor)
.WriteLine(";")
.WriteStartInstanceMethodInvocation(
"__tagHelperExecutionContext" /* ORIGINAL: ExecutionContextVariableName */,
"AddTagHelperAttribute" /* ORIGINAL: ExecutionContextAddTagHelperAttributeMethodName */)
.Write(node.VariableName)
.WriteEndMethodInvocation();
}
public override void VisitSetTagHelperProperty(SetTagHelperPropertyIRNode node)
{
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var tagHelperRenderingContext = Context.TagHelperRenderingContext;
var propertyName = node.Descriptor.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey];
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add(propertyName))
{
// Throw a reasonable Exception at runtime if the dictionary property is null.
Context.Writer
.Write("if (")
.Write(tagHelperVariableName)
.Write(".")
.Write(propertyName)
.WriteLine(" == null)");
using (Context.Writer.BuildScope())
{
// System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName
// of InvalidOperationException type.
Context.Writer
.Write("throw ")
.WriteStartNewObject(nameof(InvalidOperationException))
.WriteStartMethodInvocation("InvalidTagHelperIndexerAssignment" /* ORIGINAL: 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);
string previousValueAccessor;
if (tagHelperRenderingContext.RenderedBoundAttributes.TryGetValue(node.AttributeName, out previousValueAccessor))
{
Context.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty))
{
Context.Writer.WriteMethodInvocation("BeginWriteTagHelperAttribute" /* ORIGINAL: BeginWriteTagHelperAttributeMethodName */);
var initialRenderingConventions = Context.RenderingConventions;
Context.RenderingConventions = new CSharpLiteralCodeConventions(Context.Writer);
VisitDefault(node);
Context.RenderingConventions = initialRenderingConventions;
Context.Writer
.WriteStartAssignment("__tagHelperStringValueBuffer" /* ORIGINAL: StringValueBufferVariableName */)
.WriteMethodInvocation("EndWriteTagHelperAttribute" /* ORIGINAL: EndWriteTagHelperAttributeMethodName */)
.WriteStartAssignment(propertyValueAccessor)
.Write("__tagHelperStringValueBuffer" /* ORIGINAL: StringValueBufferVariableName */)
.WriteLine(";");
}
else
{
using (Context.Writer.BuildLinePragma(node.Source.Value))
{
Context.Writer.WriteStartAssignment(propertyValueAccessor);
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is HtmlContentIRNode)
{
Context.Writer
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
RenderTagHelperAttributeInline(node, node.Source.Value);
Context.Writer.WriteLine(";");
}
}
// We need to inform the context of the attribute value.
Context.Writer
.WriteStartInstanceMethodInvocation(
"__tagHelperExecutionContext" /* ORIGINAL: ExecutionContextVariableName */,
"AddTagHelperAttribute" /* ORIGINAL: ExecutionContextAddTagHelperAttributeMethodName */)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.Write(propertyValueAccessor)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
public override void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
{
Context.Writer
.Write("private static readonly global::")
.Write("Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute" /* ORIGINAL: TagHelperAttributeTypeName */)
.Write(" ")
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute" /* ORIGINAL: TagHelperAttributeTypeName */)
.WriteStringLiteral(node.Name);
if (node.ValueStyle == HtmlAttributeValueStyle.Minimized)
{
Context.Writer.WriteEndMethodInvocation();
}
else
{
Context.Writer
.WriteParameterSeparator()
.WriteStartNewObject("global::" + "Microsoft.AspNetCore.Html.HtmlString" /* ORIGINAL: EncodedHtmlStringTypeName */)
.WriteStringLiteral(node.Value)
.WriteEndMethodInvocation(endLine: false)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
}
public override void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
{
Context.Writer
.Write("private static readonly global::")
.Write("Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute" /* ORIGINAL: TagHelperAttributeTypeName */)
.Write(" ")
.Write(node.VariableName)
.Write(" = ")
.WriteStartNewObject("global::" + "Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute" /* ORIGINAL: TagHelperAttributeTypeName */)
.WriteStringLiteral(node.Name)
.WriteParameterSeparator()
.WriteStringLiteral(node.Value)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
private void RenderTagHelperAttributeInline(
RazorIRNode node,
SourceSpan documentLocation)
{
if (node is SetTagHelperPropertyIRNode || node is CSharpExpressionIRNode || node is HtmlContentIRNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(node.Children[i], documentLocation);
}
}
else if (node is RazorIRToken token)
{
Context.Writer.Write(token.Content);
}
else if (node is CSharpStatementIRNode)
{
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 TemplateIRNode)
{
var attributeValueNode = (SetTagHelperPropertyIRNode)node.Parent;
var expectedTypeName = attributeValueNode.IsIndexerNameMatch ?
attributeValueNode.Descriptor.IndexerTypeName :
attributeValueNode.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));
}
}
}
}

View File

@ -5,11 +5,14 @@ using System;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public 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";
@ -24,6 +27,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
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";
@ -58,7 +63,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public string MarkAsHtmlEncodedMethodName { get; set; } = "Html.Raw";
public string WriteTagHelperOutputMethod { get; set; } = "Write";
public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment";
public override void WriteDeclareTagHelperFields(CSharpRenderingContext context, DeclareTagHelperFieldsIRNode node)
{
@ -166,14 +171,10 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
.Write(attributeValueStyleParameter)
.WriteEndMethodInvocation();
// This can be removed once all the tag helper nodes are moved out of the renderers.
var initialRenderingConventions = context.RenderingConventions;
context.RenderingConventions = new TagHelperHtmlAttributeRenderingConventions(context.Writer);
using (context.Push(new TagHelperHtmlAttributeRuntimeBasicWriter()))
{
context.RenderChildren(node);
}
context.RenderingConventions = initialRenderingConventions;
context.Writer
.WriteMethodInvocation(
@ -192,15 +193,11 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
// 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.
// This can be removed once all the tag helper nodes are moved out of the renderers.
var initialRenderingConventions = context.RenderingConventions;
context.RenderingConventions = new CSharpRenderingConventions(context.Writer);
using (context.Push(new RuntimeBasicWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
context.RenderChildren(node);
}
context.RenderingConventions = initialRenderingConventions;
context.Writer
.WriteStartAssignment(StringValueBufferVariableName)
@ -296,10 +293,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
.WriteParameterSeparator();
// We remove and redirect writers so TagHelper authors can retrieve content.
// This can be removed once all the tag helper nodes are moved out of the renderers.
var initialRenderingConventions = context.RenderingConventions;
context.RenderingConventions = new CSharpRenderingConventions(context.Writer);
using (context.Push(new RuntimeBasicWriter()))
using (context.Push(new RuntimeTagHelperWriter()))
{
@ -308,14 +301,165 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
context.RenderChildren(node);
}
}
context.RenderingConventions = initialRenderingConventions;
context.Writer.WriteEndMethodInvocation();
}
public override void WriteSetTagHelperProperty(CSharpRenderingContext context, SetTagHelperPropertyIRNode node)
{
throw new NotImplementedException();
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
var tagHelperRenderingContext = context.TagHelperRenderingContext;
var propertyName = node.Descriptor.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey];
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
if (node.IsIndexerNameMatch &&
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add(propertyName))
{
// Throw a reasonable Exception at runtime if the dictionary property is null.
context.Writer
.Write("if (")
.Write(tagHelperVariableName)
.Write(".")
.Write(propertyName)
.WriteLine(" == null)");
using (context.Writer.BuildScope())
{
// System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName
// of InvalidOperationException type.
context.Writer
.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.Writer
.WriteStartAssignment(propertyValueAccessor)
.Write(previousValueAccessor)
.WriteLine(";");
return;
}
else
{
tagHelperRenderingContext.RenderedBoundAttributes[node.AttributeName] = propertyValueAccessor;
}
if (node.Descriptor.IsStringProperty || (node.IsIndexerNameMatch && node.Descriptor.IsIndexerStringProperty))
{
context.Writer.WriteMethodInvocation(BeginWriteTagHelperAttributeMethodName);
using (context.Push(new LiteralRuntimeBasicWriter()))
{
context.RenderChildren(node);
}
context.Writer
.WriteStartAssignment(StringValueBufferVariableName)
.WriteMethodInvocation(EndWriteTagHelperAttributeMethodName)
.WriteStartAssignment(propertyValueAccessor)
.Write(StringValueBufferVariableName)
.WriteLine(";");
}
else
{
using (context.Writer.BuildLinePragma(node.Source.Value))
{
context.Writer.WriteStartAssignment(propertyValueAccessor);
if (node.Descriptor.IsEnum &&
node.Children.Count == 1 &&
node.Children.First() is HtmlContentIRNode)
{
context.Writer
.Write("global::")
.Write(node.Descriptor.TypeName)
.Write(".");
}
RenderTagHelperAttributeInline(context, node, node.Source.Value);
context.Writer.WriteLine(";");
}
}
// We need to inform the context of the attribute value.
context.Writer
.WriteStartInstanceMethodInvocation(
ExecutionContextVariableName,
ExecutionContextAddTagHelperAttributeMethodName)
.WriteStringLiteral(node.AttributeName)
.WriteParameterSeparator()
.Write(propertyValueAccessor)
.WriteParameterSeparator()
.Write($"global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.{node.ValueStyle}")
.WriteEndMethodInvocation();
}
private void RenderTagHelperAttributeInline(
CSharpRenderingContext context,
RazorIRNode node,
SourceSpan documentLocation)
{
if (node is SetTagHelperPropertyIRNode || node is CSharpExpressionIRNode || node is HtmlContentIRNode)
{
for (var i = 0; i < node.Children.Count; i++)
{
RenderTagHelperAttributeInline(context, node.Children[i], documentLocation);
}
}
else if (node is RazorIRToken token)
{
context.Writer.Write(token.Content);
}
else if (node is CSharpStatementIRNode)
{
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 TemplateIRNode)
{
var attributeValueNode = (SetTagHelperPropertyIRNode)node.Parent;
var expectedTypeName = attributeValueNode.IsIndexerNameMatch ?
attributeValueNode.Descriptor.IndexerTypeName :
attributeValueNode.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.Metadata[ITagHelperBoundAttributeDescriptorBuilder.PropertyNameKey]}";
if (isIndexerNameMatch)
{
var dictionaryKey = attributeName.Substring(descriptor.IndexerNamePrefix.Length);
propertyAccessor += $"[\"{dictionaryKey}\"]";
}
return propertyAccessor;
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');

View File

@ -1,16 +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 Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class TagHelperHtmlAttributeRenderingConventions : CSharpRenderingConventions
{
public TagHelperHtmlAttributeRenderingConventions(CSharpCodeWriter writer) : base(writer)
{
}
public override string StartWriteAttributeValueMethod => "AddHtmlAttributeValue(" /* ORIGINAL: AddHtmlAttributeValueMethodName */;
}
}

View File

@ -5,7 +5,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
internal class TagHelperHtmlAttributeRuntimeBasicWriter : RuntimeBasicWriter
{
// This will be used when HtmlAttributeValueIRNode and CSharpAttributeValueIRNode are moved to writers.
public new string WriteAttributeValueMethod { get; set; } = "AddHtmlAttributeValue";
public override string WriteAttributeValueMethod { get; set; } = "AddHtmlAttributeValue";
}
}

View File

@ -21,9 +21,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
.Write(ItemParameterName).Write(" => ")
.WriteStartNewObject(TemplateTypeName);
var initialRenderingConventions = context.RenderingConventions;
context.RenderingConventions = new CSharpRedirectRenderingConventions(TemplateWriterName, context.Writer);
IDisposable basicWriterScope = null;
IDisposable tagHelperWriterScope = null;
if (!context.Options.DesignTimeMode)
@ -40,8 +37,6 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
basicWriterScope?.Dispose();
tagHelperWriterScope?.Dispose();
context.RenderingConventions = initialRenderingConventions;
context.Writer.WriteEndMethodInvocation(endLine: false);
}
}

View File

@ -1,12 +1,13 @@
// 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 Microsoft.AspNetCore.Razor.Language.Legacy;
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public class AddPreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
public class AddPreallocatedTagHelperHtmlAttributeIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children { get; } = EmptyArray;
@ -18,7 +19,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override void Accept(RazorIRNodeVisitor visitor)
{
visitor.VisitAddPreallocatedTagHelperHtmlAttribute(this);
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<AddPreallocatedTagHelperHtmlAttributeIRNode>(this, visitor);
}
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
{
var extension = target.GetExtension<IPreallocatedAttributeTargetExtension>();
extension.WriteAddPreallocatedTagHelperHtmlAttribute(context, this);
}
}
}

View File

@ -1,12 +1,14 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public class DeclarePreallocatedTagHelperAttributeIRNode : RazorIRNode
public class DeclarePreallocatedTagHelperAttributeIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children { get; } = EmptyArray;
@ -24,7 +26,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override void Accept(RazorIRNodeVisitor visitor)
{
visitor.VisitDeclarePreallocatedTagHelperAttribute(this);
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DeclarePreallocatedTagHelperAttributeIRNode>(this, visitor);
}
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
{
var extension = target.GetExtension<IPreallocatedAttributeTargetExtension>();
extension.WriteDeclarePreallocatedTagHelperAttribute(context, this);
}
}
}

View File

@ -1,12 +1,14 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public class DeclarePreallocatedTagHelperHtmlAttributeIRNode : RazorIRNode
public class DeclarePreallocatedTagHelperHtmlAttributeIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children { get; } = EmptyArray;
@ -24,7 +26,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override void Accept(RazorIRNodeVisitor visitor)
{
visitor.VisitDeclarePreallocatedTagHelperHtmlAttribute(this);
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DeclarePreallocatedTagHelperHtmlAttributeIRNode>(this, visitor);
}
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
{
var extension = target.GetExtension<IPreallocatedAttributeTargetExtension>();
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, this);
}
}
}

View File

@ -0,0 +1,34 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
internal class DesignTimeDirectiveIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
public override RazorIRNode Parent { get; set; }
public override SourceSpan? Source { get; set; }
public override void Accept(RazorIRNodeVisitor visitor)
{
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<DesignTimeDirectiveIRNode>(this, visitor);
}
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
{
var extension = target.GetExtension<IDesignTimeDirectiveTargetExtension>();
extension.WriteDesignTimeDirective(context, this);
}
}
}

View File

@ -1,8 +1,8 @@
// Copyright(c) .NET Foundation.All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{

View File

@ -128,25 +128,5 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
VisitDefault(node);
}
public virtual void VisitDeclarePreallocatedTagHelperHtmlAttribute(DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
{
VisitDefault(node);
}
public virtual void VisitAddPreallocatedTagHelperHtmlAttribute(AddPreallocatedTagHelperHtmlAttributeIRNode node)
{
VisitDefault(node);
}
public virtual void VisitDeclarePreallocatedTagHelperAttribute(DeclarePreallocatedTagHelperAttributeIRNode node)
{
VisitDefault(node);
}
public virtual void VisitSetPreallocatedTagHelperProperty(SetPreallocatedTagHelperPropertyIRNode node)
{
VisitDefault(node);
}
}
}

View File

@ -1,12 +1,14 @@
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
using Microsoft.AspNetCore.Razor.Language.Legacy;
namespace Microsoft.AspNetCore.Razor.Language.Intermediate
{
public class SetPreallocatedTagHelperPropertyIRNode : RazorIRNode
public class SetPreallocatedTagHelperPropertyIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children { get; } = EmptyArray;
@ -30,7 +32,18 @@ namespace Microsoft.AspNetCore.Razor.Language.Intermediate
public override void Accept(RazorIRNodeVisitor visitor)
{
visitor.VisitSetPreallocatedTagHelperProperty(this);
if (visitor == null)
{
throw new ArgumentNullException(nameof(visitor));
}
AcceptExtensionNode<SetPreallocatedTagHelperPropertyIRNode>(this, visitor);
}
public override void WriteNode(RuntimeTarget target, CSharpRenderingContext context)
{
var extension = target.GetExtension<IPreallocatedAttributeTargetExtension>();
extension.WriteSetPreallocatedTagHelperProperty(context, this);
}
}
}

View File

@ -1,7 +1,6 @@
// 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 Microsoft.AspNetCore.Razor.Language.Intermediate;
namespace Microsoft.AspNetCore.Razor.Language
@ -21,7 +20,7 @@ namespace Microsoft.AspNetCore.Razor.Language
internal class DesignTimeHelperWalker : RazorIRNodeWalker
{
private DirectiveTokenHelperIRNode _directiveTokenHelper;
private DesignTimeDirectiveIRNode _designTimeDirectiveIRNode;
public override void VisitClass(ClassDeclarationIRNode node)
{
@ -35,77 +34,16 @@ namespace Microsoft.AspNetCore.Razor.Language
node.Children.Insert(0, designTimeHelperDeclaration);
_directiveTokenHelper = new DirectiveTokenHelperIRNode();
_designTimeDirectiveIRNode = new DesignTimeDirectiveIRNode();
VisitDefault(node);
node.Children.Insert(0, _directiveTokenHelper);
node.Children.Insert(0, _designTimeDirectiveIRNode);
}
public override void VisitDirectiveToken(DirectiveTokenIRNode node)
{
_directiveTokenHelper.AddToMethodBody(node);
}
private class DirectiveTokenHelperIRNode : RazorIRNode
{
private const string DirectiveTokenHelperMethodName = "__RazorDirectiveTokenHelpers__";
private int _methodBodyIndex = 2;
public DirectiveTokenHelperIRNode()
{
var disableWarningPragma = new CSharpStatementIRNode();
RazorIRBuilder.Create(disableWarningPragma)
.Add(new RazorIRToken()
{
Kind = RazorIRToken.TokenKind.CSharp,
Content = "#pragma warning disable 219",
});
Children.Add(disableWarningPragma);
var methodStartNode = new CSharpStatementIRNode();
RazorIRBuilder.Create(methodStartNode)
.Add(new RazorIRToken()
{
Kind = RazorIRToken.TokenKind.CSharp,
Content = "private void " + DirectiveTokenHelperMethodName + "() {"
});
Children.Add(methodStartNode);
var methodEndNode = new CSharpStatementIRNode();
RazorIRBuilder.Create(methodEndNode)
.Add(new RazorIRToken()
{
Kind = RazorIRToken.TokenKind.CSharp,
Content = "}"
});
Children.Add(methodEndNode);
var restoreWarningPragma = new CSharpStatementIRNode();
RazorIRBuilder.Create(restoreWarningPragma)
.Add(new RazorIRToken()
{
Kind = RazorIRToken.TokenKind.CSharp,
Content = "#pragma warning restore 219",
});
Children.Add(restoreWarningPragma);
}
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
public override RazorIRNode Parent { get; set; }
public override SourceSpan? Source { get; set; }
public void AddToMethodBody(RazorIRNode node)
{
Children.Insert(_methodBodyIndex++, node);
}
public override void Accept(RazorIRNodeVisitor visitor)
{
visitor.VisitDefault(this);
}
_designTimeDirectiveIRNode.Children.Add(node);
}
}
}

View File

@ -75,6 +75,7 @@ namespace Microsoft.AspNetCore.Razor.Language
// Default Runtime Targets
builder.AddTargetExtension(new TemplateTargetExtension());
builder.AddTargetExtension(new PreallocatedAttributeTargetExtension());
// Default configuration
var configurationFeature = new DefaultDocumentClassifierPassFeature();
@ -107,8 +108,14 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static void AddDesignTimeDefaults(IRazorEngineBuilder builder)
{
// Configure options
builder.Features.Add(new DesignTimeParserOptionsFeature());
// IR Passes
builder.Features.Add(new RazorDesignTimeIRPass());
// DesignTime Runtime Targets
builder.AddTargetExtension(new DesignTimeDirectiveTargetExtension());
}
public abstract IReadOnlyList<IRazorEngineFeature> Features { get; }

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Basic_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -28,10 +24,6 @@ Document -
DirectiveToken - (586:11,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithModel_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -33,10 +29,6 @@ Document -
DirectiveToken - (30:1,14 [14] InjectWithModel.cshtml) - MyPropertyName
DirectiveToken - (54:2,8 [17] InjectWithModel.cshtml) - MyService<TModel>
DirectiveToken - (72:2,26 [4] InjectWithModel.cshtml) - Html
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InjectWithSemicolon_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<MyModel> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -37,10 +33,6 @@ Document -
DirectiveToken - (99:3,14 [15] InjectWithSemicolon.cshtml) - MyPropertyName2
DirectiveToken - (129:4,8 [17] InjectWithSemicolon.cshtml) - MyService<TModel>
DirectiveToken - (147:4,26 [5] InjectWithSemicolon.cshtml) - Html2
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -11,11 +11,7 @@ Document -
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingStatement - (1:0,1 [17] Inject.cshtml) - MyNamespace
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inject_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -31,10 +27,6 @@ Document -
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (28:1,8 [5] Inject.cshtml) - MyApp
DirectiveToken - (34:1,14 [14] Inject.cshtml) - MyPropertyName
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -29,10 +25,6 @@ Document -
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (6:0,6 [4] MalformedPageDirective.cshtml) - "foo
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ModelExpressionTagHelper_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<DateTime> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -30,10 +26,6 @@ Document -
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (7:0,7 [8] ModelExpressionTagHelper.cshtml) - DateTime
DirectiveToken - (33:2,14 [108] ModelExpressionTagHelper.cshtml) - Microsoft.AspNetCore.Mvc.Razor.Extensions.InputTestTagHelper, Microsoft.AspNetCore.Mvc.Razor.Extensions.Test
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - Microsoft.AspNetCore.Mvc.Razor.Extensions.InputTestTagHelper

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Model_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<System.Collections.IEnumerable> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -29,10 +25,6 @@ Document -
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (7:0,7 [30] Model.cshtml) - System.Collections.IEnumerable
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MultipleModels_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<System.Collections.IEnumerable> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -30,10 +26,6 @@ Document -
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (7:0,7 [21] MultipleModels.cshtml) - ThisShouldBeGenerated
DirectiveToken - (37:1,7 [30] MultipleModels.cshtml) - System.Collections.IEnumerable
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - PageWithNamespace_Page - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -29,10 +25,6 @@ Document -
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (18:1,11 [14] PageWithNamespace.cshtml) - Test.Namespace
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -11,11 +11,7 @@ Document -
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingStatement - (43:3,1 [41] RazorPagesWithoutModel.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPagesWithoutModel_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -30,10 +26,6 @@ Document -
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (23:2,14 [17] RazorPagesWithoutModel.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - DivTagHelper

View File

@ -11,11 +11,7 @@ Document -
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
UsingStatement - (60:4,1 [41] RazorPages.cshtml) - Microsoft.AspNetCore.Mvc.RazorPages
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorPages_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -31,10 +27,6 @@ Document -
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (16:2,7 [8] RazorPages.cshtml) - NewModel
DirectiveToken - (40:3,14 [17] RazorPages.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - DivTagHelper

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - ViewWithNamespace_View - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -29,10 +25,6 @@ Document -
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (11:0,11 [14] ViewWithNamespace.cshtml) - Test.Namespace
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -10,11 +10,7 @@ Document -
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest__ViewImports_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic> -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
@ -30,10 +26,6 @@ Document -
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (8:0,8 [19] _ViewImports.cshtml) - IHtmlHelper<TModel>
DirectiveToken - (28:0,28 [5] _ViewImports.cshtml) - Model
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync

View File

@ -22,9 +22,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Options = options,
Writer = new Legacy.CSharpCodeWriter(),
};
var renderer = new RuntimeCSharpRenderer(target, context);
var writer = new DefaultDocumentWriter(target, context, renderer);
var writer = new DefaultDocumentWriter(target, context);
var builder = RazorIRBuilder.Document();
builder.Add(new NamespaceDeclarationIRNode()
@ -62,9 +61,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Options = options,
Writer = new Legacy.CSharpCodeWriter(),
};
var renderer = new RuntimeCSharpRenderer(target, context);
var writer = new DefaultDocumentWriter(target, context, renderer);
var writer = new DefaultDocumentWriter(target, context);
var builder = RazorIRBuilder.Document();
builder.Add(new ClassDeclarationIRNode()
@ -104,9 +101,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
Options = options,
Writer = new Legacy.CSharpCodeWriter(),
};
var renderer = new RuntimeCSharpRenderer(target, context);
var writer = new DefaultDocumentWriter(target, context, renderer);
var writer = new DefaultDocumentWriter(target, context);
var builder = RazorIRBuilder.Document();
builder.Add(new RazorMethodDeclarationIRNode()

View File

@ -10,6 +10,72 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class DesignTimeBasicWriterTest
{
[Fact]
public void WriteUsingStatement_NoSource_WritesContent()
{
// Arrange
var writer = new DesignTimeBasicWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter()
};
var node = new UsingStatementIRNode()
{
Content = "System",
};
// Act
writer.WriteUsingStatement(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"using System;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteUsingStatement_WithSource_WritesContentWithLinePragmaAndMapping()
{
// Arrange
var writer = new DesignTimeBasicWriter();
var sourceDocument = TestRazorSourceDocument.Create("@using System;");
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(sourceDocument)
};
var originalSpan = new SourceSpan("test.cshtml", 0, 0, 0, 6);
var generatedSpan = new SourceSpan(null, 23, 1, 0, 6);
var expectedLineMapping = new LineMapping(originalSpan, generatedSpan);
var node = new UsingStatementIRNode()
{
Content = "System",
Source = originalSpan,
};
// Act
writer.WriteUsingStatement(context, node);
// Assert
var mapping = Assert.Single(context.LineMappings);
Assert.Equal(expectedLineMapping, mapping);
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
using System;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpExpression_SkipsLinePragma_WithoutSource()
{

View File

@ -0,0 +1,258 @@
// 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.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class DesignTimeDirectiveTargetExtensionTest
{
[Fact]
public void WriteDesignTimeDirective_NoChildren_WritesEmptyMethod_WithPragma()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var node = new DesignTimeDirectiveIRNode();
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDesignTimeDirective_WithTypeToken_WritesLambda()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("test content", "test.cshtml"))
};
var node = new DesignTimeDirectiveIRNode();
var token = new DirectiveTokenIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
Content = "System.String",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.Type
}
};
node.Children.Add(token);
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
System.String __typeHelper = null;
}
))();
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDesignTimeDirective_WithNamespaceToken_WritesLambda()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("test content", "test.cshtml"))
};
var node = new DesignTimeDirectiveIRNode();
var token = new DirectiveTokenIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
Content = "System.Collections.Generic",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.Namespace
}
};
node.Children.Add(token);
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
global::System.Object __typeHelper = nameof(System.Collections.Generic);
}
))();
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDesignTimeDirective_WithMemberToken_WritesLambda()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("test content", "test.cshtml"))
};
var node = new DesignTimeDirectiveIRNode();
var token = new DirectiveTokenIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
Content = "Foo",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.Member
}
};
node.Children.Add(token);
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
global::System.Object Foo = null;
}
))();
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDesignTimeDirective_WithStringToken_WritesLambda()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("test content", "test.cshtml"))
};
var node = new DesignTimeDirectiveIRNode();
var token = new DirectiveTokenIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
Content = "Value",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.String
}
};
var tokenWithQuotedContent = new DirectiveTokenIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
Content = "\"Value\"",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.String
}
};
node.Children.Add(token);
node.Children.Add(tokenWithQuotedContent);
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
((System.Action)(() => {
global::System.Object __typeHelper = ""Value"";
}
))();
((System.Action)(() => {
global::System.Object __typeHelper = ""Value"";
}
))();
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDesignTimeDirective_ChildrenWithNoSource_WritesEmptyMethod_WithPragma()
{
// Arrange
var extension = new DesignTimeDirectiveTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter(),
CodeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("test content", "test.cshtml"))
};
var node = new DesignTimeDirectiveIRNode();
var token = new DirectiveTokenIRNode()
{
Content = "Value",
Descriptor = new DirectiveTokenDescriptor()
{
Kind = DirectiveTokenKind.String
}
};
node.Children.Add(token);
// Act
extension.WriteDesignTimeDirective(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#pragma warning restore 219
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}

View File

@ -1,6 +1,9 @@
// 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;
@ -13,10 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
// Arrange
var writer = new DesignTimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var context = GetCSharpRenderingContext(writer);
var node = new DeclareTagHelperFieldsIRNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
@ -39,10 +39,7 @@ private global::MyTagHelper __MyTagHelper = null;
{
// Arrange
var writer = new DesignTimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var context = GetCSharpRenderingContext(writer);
var node = new CreateTagHelperIRNode()
{
TagHelperTypeName = "TestNamespace.MyTagHelper"
@ -59,5 +56,211 @@ private global::MyTagHelper __MyTagHelper = null;
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<ITagHelperBoundAttributeDescriptorBuilder>[]
{
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 SetTagHelperPropertyIRNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.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<ITagHelperBoundAttributeDescriptorBuilder>[]
{
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 SetTagHelperPropertyIRNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.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<ITagHelperBoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionary("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 SetTagHelperPropertyIRNode;
var writer = new DesignTimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 3 ""test.cshtml""
__InputTagHelper.FooProp[""bound""] = 42;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CSharpRenderingContext GetCSharpRenderingContext(TagHelperWriter writer, RazorCodeDocument codeDocument = null)
{
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = new DesignTimeBasicWriter(),
TagHelperWriter = writer,
TagHelperRenderingContext = new TagHelperRenderingContext(),
CodeDocument = codeDocument,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
return context;
}
private static DocumentIRNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIRNode 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 IRazorIRLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetIRDocument();
Assert.NotNull(irDocument);
return irDocument;
}
private static TagHelperDescriptor CreateTagHelperDescriptor(
string tagName,
string typeName,
string assemblyName,
IEnumerable<Action<ITagHelperBoundAttributeDescriptorBuilder>> attributes = null)
{
var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
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

@ -0,0 +1,50 @@
// 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.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class LiteralRuntimeBasicWriterTest
{
[Fact]
public void WriteCSharpExpression_UsesWriteLiteral_WritesLinePragma_WithSource()
{
// Arrange
var writer = new LiteralRuntimeBasicWriter();
var context = new CSharpRenderingContext()
{
Options = RazorParserOptions.CreateDefaultOptions(),
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new CSharpExpressionIRNode()
{
Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
};
var builder = RazorIRBuilder.Create(node);
builder.Add(new RazorIRToken()
{
Content = "i++",
Kind = RazorIRToken.TokenKind.CSharp,
});
// Act
writer.WriteCSharpExpression(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
WriteLiteral(i++);
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}

View File

@ -0,0 +1,207 @@
// 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.Intermediate;
using Microsoft.AspNetCore.Razor.Language.Legacy;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class PreallocatedAttributeTargetExtensionTest
{
[Fact]
public void WriteDeclarePreallocatedTagHelperHtmlAttribute_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var node = new DeclarePreallocatedTagHelperHtmlAttributeIRNode()
{
Name = "Foo",
Value = "Bar",
ValueStyle = HtmlAttributeValueStyle.DoubleQuotes,
VariableName = "MyProp"
};
// Act
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute MyProp = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"", new global::Microsoft.AspNetCore.Html.HtmlString(""Bar""), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDeclarePreallocatedTagHelperHtmlAttribute_Minimized_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var node = new DeclarePreallocatedTagHelperHtmlAttributeIRNode()
{
Name = "Foo",
Value = "Bar",
ValueStyle = HtmlAttributeValueStyle.Minimized,
VariableName = "_tagHelper1"
};
// Act
extension.WriteDeclarePreallocatedTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute _tagHelper1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"");
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteAddPreallocatedTagHelperHtmlAttribute_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var node = new AddPreallocatedTagHelperHtmlAttributeIRNode()
{
VariableName = "_tagHelper1"
};
// Act
extension.WriteAddPreallocatedTagHelperHtmlAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"__tagHelperExecutionContext.AddHtmlAttribute(_tagHelper1);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDeclarePreallocatedTagHelperAttribute_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var node = new DeclarePreallocatedTagHelperAttributeIRNode()
{
Name = "Foo",
Value = "Bar",
ValueStyle = HtmlAttributeValueStyle.DoubleQuotes,
VariableName = "_tagHelper1",
};
// Act
extension.WriteDeclarePreallocatedTagHelperAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute _tagHelper1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"", ""Bar"", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetPreallocatedTagHelperProperty_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var descriptor = ITagHelperBoundAttributeDescriptorBuilder
.Create("FooTagHelper")
.Name("Foo")
.TypeName("System.String")
.PropertyName("FooProp")
.Build();
var node = new SetPreallocatedTagHelperPropertyIRNode()
{
AttributeName = descriptor.Name,
TagHelperTypeName = "FooTagHelper",
VariableName = "_tagHelper1",
Descriptor = descriptor,
};
// Act
extension.WriteSetPreallocatedTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"__FooTagHelper.FooProp = (string)_tagHelper1.Value;
__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_RendersCorrectly()
{
// Arrange
var extension = new PreallocatedAttributeTargetExtension();
var context = new CSharpRenderingContext()
{
Writer = new CSharpCodeWriter()
};
var descriptor = ITagHelperBoundAttributeDescriptorBuilder
.Create("FooTagHelper")
.Name("Foo")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
.AsDictionary("pre-", "System.String")
.PropertyName("FooProp")
.Build();
var node = new SetPreallocatedTagHelperPropertyIRNode()
{
AttributeName = "pre-Foo",
TagHelperTypeName = "FooTagHelper",
VariableName = "_tagHelper1",
Descriptor = descriptor,
IsIndexerNameMatch = true
};
// Act
extension.WriteSetPreallocatedTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}

View File

@ -3,12 +3,13 @@
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 RedirectedBasicWriterTest
public class RedirectedRuntimeBasicWriterTest
{
[Fact]
public void WriteCSharpExpression_Runtime_SkipsLinePragma_WithoutSource()
@ -243,6 +244,155 @@ WriteLiteralTo(test_writer, @""{1}"");
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteHtmlAttribute_RendersCorrectly()
{
var writer = new RedirectedRuntimeBasicWriter("test_writer");
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single();
// Act
writer.WriteHtmlAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"BeginWriteAttributeTo(test_writer, ""checked"", "" checked=\"""", 6, ""\"""", 34, 2);
Render Children
EndWriteAttributeTo(test_writer);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteHtmlAttributeValue_RendersCorrectly()
{
var writer = new RedirectedRuntimeBasicWriter("test_writer");
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[0] as HtmlAttributeValueIRNode;
// Act
writer.WriteHtmlAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"WriteAttributeValueTo(test_writer, """", 16, ""hello-world"", 16, 11, true);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_RendersCorrectly()
{
var writer = new RedirectedRuntimeBasicWriter("test_writer");
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
WriteAttributeValueTo(test_writer, "" "", 27, false, 28, 6, false);
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_NonExpression_BuffersResult()
{
var writer = new RedirectedRuntimeBasicWriter("test_writer");
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @if(@true){ }\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"WriteAttributeValueTo(test_writer, "" "", 27, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
Render Children
}
), 28, 13, false);
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CSharpRenderingContext GetCSharpRenderingContext(BasicWriter writer)
{
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
return context;
}
private static DocumentIRNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIRNode 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 IRazorIRLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetIRDocument();
Assert.NotNull(irDocument);
return irDocument;
}
private class MyExtensionIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children => throw new NotImplementedException();

View File

@ -1,14 +1,12 @@
// 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 Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class RedirectedTagHelperWriterTest
public class RedirectedRuntimeTagHelperWriterTest
{
[Fact]
public void WriteExecuteTagHelpers_Runtime_RendersWithRedirectWriter()

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
@ -10,6 +11,119 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class RuntimeBasicWriterTest
{
[Fact]
public void WriteChecksum_WritesPragmaChecksum()
{
// Arrange
var writer = new RuntimeBasicWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter()
};
var node = new ChecksumIRNode()
{
FileName = "test.cshtml",
Guid = "SomeGuid",
Bytes = "SomeFileHash"
};
// Act
writer.WriteChecksum(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#pragma checksum ""test.cshtml"" ""SomeGuid"" ""SomeFileHash""
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteChecksum_EmptyBytes_WritesNothing()
{
// Arrange
var writer = new RuntimeBasicWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter()
};
var node = new ChecksumIRNode()
{
FileName = "test.cshtml",
Guid = "SomeGuid",
Bytes = string.Empty
};
// Act
writer.WriteChecksum(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Empty(csharp);
}
[Fact]
public void WriteUsingStatement_NoSource_WritesContent()
{
// Arrange
var writer = new RuntimeBasicWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter()
};
var node = new UsingStatementIRNode()
{
Content = "System",
};
// Act
writer.WriteUsingStatement(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"using System;
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteUsingStatement_WithSource_WritesContentWithLinePragma()
{
// Arrange
var writer = new RuntimeBasicWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter()
};
var node = new UsingStatementIRNode()
{
Content = "System",
Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
};
// Act
writer.WriteUsingStatement(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
using System;
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpExpression_SkipsLinePragma_WithoutSource()
{
@ -378,6 +492,155 @@ WriteLiteral(@""{1}"");
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteHtmlAttribute_RendersCorrectly()
{
var writer = new RuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single();
// Act
writer.WriteHtmlAttribute(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"BeginWriteAttribute(""checked"", "" checked=\"""", 6, ""\"""", 34, 2);
Render Children
EndWriteAttribute();
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteHtmlAttributeValue_RendersCorrectly()
{
var writer = new RuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[0] as HtmlAttributeValueIRNode;
// Act
writer.WriteHtmlAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"WriteAttributeValue("""", 16, ""hello-world"", 16, 11, true);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_RendersCorrectly()
{
var writer = new RuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
WriteAttributeValue("" "", 27, false, 28, 6, false);
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_NonExpression_BuffersResult()
{
var writer = new RuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @if(@true){ }\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"WriteAttributeValue("" "", 27, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
Render Children
}
), 28, 13, false);
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CSharpRenderingContext GetCSharpRenderingContext(BasicWriter writer)
{
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
return context;
}
private static DocumentIRNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIRNode 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 IRazorIRLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetIRDocument();
Assert.NotNull(irDocument);
return irDocument;
}
private class MyExtensionIRNode : ExtensionIRNode
{
public override IList<RazorIRNode> Children => throw new NotImplementedException();

View File

@ -15,12 +15,9 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
public void WriteDeclareTagHelperFields_DeclaresRequiredFields()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new DeclareTagHelperFieldsIRNode();
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer);
// Act
writer.WriteDeclareTagHelperFields(context, node);
@ -55,15 +52,13 @@ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeMana
public void WriteDeclareTagHelperFields_DeclaresUsedTagHelperTypes()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new DeclareTagHelperFieldsIRNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer);
// Act
writer.WriteDeclareTagHelperFields(context, node);
@ -99,20 +94,14 @@ private global::MyTagHelper __MyTagHelper = null;
public void WriteInitializeTagHelperStructure_RendersCorrectly_UsesTagNameAndModeFromIRNode()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
BasicWriter = new RuntimeBasicWriter(),
TagHelperWriter = new RuntimeTagHelperWriter(),
IdGenerator = () => "test",
RenderChildren = n => { }
};
var node = new InitializeTagHelperStructureIRNode()
{
TagName = "p",
TagMode = TagMode.SelfClosing
};
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer);
context.IdGenerator = () => "test";
// Act
writer.WriteInitializeTagHelperStructure(context, node);
@ -121,6 +110,7 @@ private global::MyTagHelper __MyTagHelper = null;
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"__tagHelperExecutionContext = __tagHelperScopeManager.Begin(""p"", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, ""test"", async() => {
Render Children
}
);
",
@ -132,15 +122,12 @@ private global::MyTagHelper __MyTagHelper = null;
public void WriteCreateTagHelper_RendersCorrectly_UsesSpecifiedTagHelperType()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new CreateTagHelperIRNode()
{
TagHelperTypeName = "TestNamespace.MyTagHelper"
};
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer);
// Act
writer.WriteCreateTagHelper(context, node);
@ -159,12 +146,9 @@ __tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
public void WriteExecuteTagHelpers_RendersCorrectly()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new ExecuteTagHelpersIRNode();
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer);
// Act
writer.WriteExecuteTagHelpers(context, node);
@ -188,21 +172,6 @@ __tagHelperExecutionContext = __tagHelperScopeManager.End();
public void WriteAddTagHelperHtmlAttribute_RendersCorrectly()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = new RuntimeBasicWriter(),
TagHelperWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
var descriptors = new[]
{
CreateTagHelperDescriptor(
@ -219,6 +188,9 @@ __tagHelperExecutionContext = __tagHelperScopeManager.End();
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
@ -238,21 +210,6 @@ __tagHelperExecutionContext.AddHtmlAttribute(""name"", Html.Raw(__tagHelperStrin
public void WriteAddTagHelperHtmlAttribute_DataAttribute_RendersCorrectly()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = new RuntimeBasicWriter(),
TagHelperWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
var descriptors = new[]
{
CreateTagHelperDescriptor(
@ -269,6 +226,9 @@ __tagHelperExecutionContext.AddHtmlAttribute(""name"", Html.Raw(__tagHelperStrin
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
@ -288,21 +248,6 @@ __tagHelperExecutionContext.AddHtmlAttribute(""data-test"", Html.Raw(__tagHelper
public void WriteAddTagHelperHtmlAttribute_DynamicAttribute_RendersCorrectly()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = new RuntimeBasicWriter(),
TagHelperWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
var descriptors = new[]
{
CreateTagHelperDescriptor(
@ -319,6 +264,9 @@ __tagHelperExecutionContext.AddHtmlAttribute(""data-test"", Html.Raw(__tagHelper
var irDocument = Lower(codeDocument, engine);
var node = irDocument.Children.Last().Children[2] as AddTagHelperHtmlAttributeIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteAddTagHelperHtmlAttribute(context, node);
@ -333,6 +281,173 @@ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteSetTagHelperProperty_RendersCorrectly()
{
// Arrange
var descriptors = new[]
{
CreateTagHelperDescriptor(
tagName: "input",
typeName: "InputTagHelper",
assemblyName: "TestAssembly",
attributes: new Action<ITagHelperBoundAttributeDescriptorBuilder>[]
{
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 SetTagHelperPropertyIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.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<ITagHelperBoundAttributeDescriptorBuilder>[]
{
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 SetTagHelperPropertyIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.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<ITagHelperBoundAttributeDescriptorBuilder>[]
{
builder => builder
.Name("bound")
.PropertyName("FooProp")
.TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
.AsDictionary("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 SetTagHelperPropertyIRNode;
var writer = new RuntimeTagHelperWriter();
var context = GetCSharpRenderingContext(writer, codeDocument);
// Act
writer.WriteSetTagHelperProperty(context, node);
// Assert
var csharp = context.Writer.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 CSharpRenderingContext GetCSharpRenderingContext(TagHelperWriter writer, RazorCodeDocument codeDocument = null)
{
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = new RuntimeBasicWriter(),
TagHelperWriter = writer,
TagHelperRenderingContext = new TagHelperRenderingContext(),
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
return context;
}
private static DocumentIRNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();

View File

@ -0,0 +1,135 @@
// 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 Microsoft.AspNetCore.Razor.Language.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
public class TagHelperHtmlAttributeRuntimeBasicWriterTest
{
[Fact]
public void WriteHtmlAttributeValue_RendersCorrectly()
{
var writer = new TagHelperHtmlAttributeRuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[0] as HtmlAttributeValueIRNode;
// Act
writer.WriteHtmlAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"AddHtmlAttributeValue("""", 16, ""hello-world"", 16, 11, true);
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_RendersCorrectly()
{
var writer = new TagHelperHtmlAttributeRuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @false\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line 1 ""test.cshtml""
AddHtmlAttributeValue("" "", 27, false, 28, 6, false);
#line default
#line hidden
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteCSharpAttributeValue_NonExpression_BuffersResult()
{
var writer = new TagHelperHtmlAttributeRuntimeBasicWriter();
var context = GetCSharpRenderingContext(writer);
var content = "<input checked=\"hello-world @if(@true){ }\" />";
var sourceDocument = TestRazorSourceDocument.Create(content);
var codeDocument = RazorCodeDocument.Create(sourceDocument);
var irDocument = Lower(codeDocument);
var node = irDocument.Children.OfType<HtmlAttributeIRNode>().Single().Children[1] as CSharpAttributeValueIRNode;
// Act
writer.WriteCSharpAttributeValue(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"AddHtmlAttributeValue("" "", 27, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
Render Children
}
), 28, 13, false);
",
csharp,
ignoreLineEndingDifferences: true);
}
private static CSharpRenderingContext GetCSharpRenderingContext(BasicWriter writer)
{
var options = RazorParserOptions.CreateDefaultOptions();
var codeWriter = new Legacy.CSharpCodeWriter();
var context = new CSharpRenderingContext()
{
Writer = codeWriter,
Options = options,
BasicWriter = writer,
RenderChildren = n =>
{
codeWriter.WriteLine("Render Children");
}
};
return context;
}
private static DocumentIRNode Lower(RazorCodeDocument codeDocument)
{
var engine = RazorEngine.Create();
return Lower(codeDocument, engine);
}
private static DocumentIRNode 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 IRazorIRLoweringPhase)
{
break;
}
}
var irDocument = codeDocument.GetIRDocument();
Assert.NotNull(irDocument);
return irDocument;
}
}
}

View File

@ -32,8 +32,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
{
Assert.Same(node, n);
var conventions = Assert.IsType<CSharpRedirectRenderingConventions>(context.RenderingConventions);
Assert.Equal("__razor_template_writer", conventions.RedirectWriter);
Assert.IsType<RedirectedRuntimeBasicWriter>(context.BasicWriter);
context.Writer.Write(" var s = \"Inside\"");
};

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AddTagHelperDirective_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] AddTagHelperDirective.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [15] AttributeTargetingTagHelpers.cshtml) - *, TestAssembly
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.CatchAllTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -7,16 +7,8 @@ Document -
UsingStatement - (80:3,1 [27] BasicImports_Imports0.cshtml) - System.ComponentModel
UsingStatement - (23:1,1 [18] BasicImports_Imports1.cshtml) - System.Text
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_DesignTime - Hello -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (119:4,10 [5] BasicImports_Imports0.cshtml) - Hello
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] BasicTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,17 +4,9 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (17:0,17 [5] BasicTagHelpers_Prefixed.cshtml) - "THS"
DirectiveToken - (38:1,14 [17] BasicTagHelpers_Prefixed.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] ComplexTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DesignTime_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (173:11,9 [6] DesignTime.cshtml) - Footer
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] DuplicateAttributeTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] DynamicAttributeTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.InputTagHelper

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [15] EmptyAttributeTagHelpers.cshtml) - *, TestAssembly
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2 - TestNamespace.PTagHelper

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] EnumTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.InputTagHelper - TestNamespace.CatchAllTagHelper

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [15] EscapedTagHelpers.cshtml) - *, TestAssembly
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.InputTagHelper - TestNamespace.InputTagHelper2

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] IncompleteTagHelper.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.PTagHelper

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_DesignTime - foo.bar<baz<biz>>.boz -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (20:2,10 [21] Inherits.cshtml) - foo.bar<baz<biz>>.boz
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (9:0,9 [4] InlineBlocks.cshtml) - Link
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,16 +4,8 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DesignTimeDirective -
DirectiveToken - (14:0,14 [17] MinimizedTagHelpers.cshtml) - "*, TestAssembly"
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
DeclareTagHelperFields - - TestNamespace.CatchAllTagHelper - TestNamespace.InputTagHelper

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

View File

@ -4,15 +4,7 @@ Document -
UsingStatement - - System
UsingStatement - - System.Threading.Tasks
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_DesignTime - -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
DesignTimeDirective -
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async - System.Threading.Tasks.Task - ExecuteAsync

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