Handle complex expressions for bound non-string tag helper attributes
- #129 and support aspnet/Mvc#1253 - add new `CSharpTagHelperAttributeValueVisitor` that writes the raw expression - add tests of embedded `@(...)` and mix that with normal expressions - add new resources for errors in `CSharpTagHelperAttributeValueVisitor` - write errors using `ParserErrorSink` - update baselines to match new code generation nits: - cleanup long lines in `CSharpTagHelperCodeRenderer` - remove a few unused resources
This commit is contained in:
parent
7b8126367c
commit
de4cafa8cd
|
|
@ -5,8 +5,8 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.Text;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||
{
|
||||
|
|
@ -230,48 +230,67 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
|||
tagHelperVariableName,
|
||||
attributeDescriptor.PropertyName);
|
||||
|
||||
_writer.WriteStartAssignment(valueAccessor);
|
||||
|
||||
// If we haven't recorded this attribute value before then we need to record its value.
|
||||
if (!attributeValueRecorded)
|
||||
{
|
||||
// We only need to create attribute values once per HTML element (not once per tag helper).
|
||||
// We're saving the value accessor so we can retrieve it later if there are more tag helpers that
|
||||
// need the value.
|
||||
// We're saving the value accessor so we can retrieve it later if there are more tag
|
||||
// helpers that need the value.
|
||||
htmlAttributeValues.Add(attributeDescriptor.Name, valueAccessor);
|
||||
|
||||
if (bufferableAttribute)
|
||||
{
|
||||
// If the attribute is bufferable but has a plain text value that means the value
|
||||
// is a string which needs to be surrounded in quotes.
|
||||
_writer.WriteStartAssignment(valueAccessor);
|
||||
|
||||
if (isPlainTextValue)
|
||||
{
|
||||
// If the attribute is bufferable but has a plain text value that means the value
|
||||
// is a string which needs to be surrounded in quotes.
|
||||
RenderQuotedAttributeValue(textValue, attributeDescriptor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The value contains more than plain text. e.g. someAttribute="Time: @DateTime.Now"
|
||||
// The value contains more than plain text e.g.
|
||||
// stringAttribute ="Time: @DateTime.Now"
|
||||
RenderBufferedAttributeValue(attributeDescriptor);
|
||||
}
|
||||
|
||||
_writer.WriteLine(";");
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Make complex types in non-bufferable attributes work in
|
||||
// https://github.com/aspnet/Razor/issues/129
|
||||
if (!isPlainTextValue)
|
||||
// Write out simple assignment for non-string property value. Try to keep the whole
|
||||
// statement together and the #line pragma correct to make debugging possible.
|
||||
using (var lineMapper = new CSharpLineMappingWriter(
|
||||
_writer,
|
||||
attributeValueChunk.Association.Start,
|
||||
_context.SourceFile))
|
||||
{
|
||||
// Place the assignment LHS to align RHS with original attribute value's indentation.
|
||||
// Unfortunately originalIndent is incorrect if original line contains tabs. Unable to
|
||||
// use a CSharpPaddingBuilder because the Association has no Previous node; lost the
|
||||
// original Span sequence when the parse tree was rewritten.
|
||||
var originalIndent = attributeValueChunk.Start.CharacterIndex;
|
||||
var generatedLength = valueAccessor.Length + " = ".Length;
|
||||
var newIndent = originalIndent - generatedLength;
|
||||
if (newIndent > 0)
|
||||
{
|
||||
_writer.Indent(newIndent);
|
||||
}
|
||||
|
||||
_writer.WriteStartAssignment(valueAccessor);
|
||||
lineMapper.MarkLineMappingStart();
|
||||
|
||||
// Write out bare expression for this attribute value. Property is not a string.
|
||||
// So quoting or buffering are not helpful.
|
||||
RenderRawAttributeValue(attributeValueChunk, attributeDescriptor, isPlainTextValue);
|
||||
|
||||
// End the assignment to the attribute.
|
||||
lineMapper.MarkLineMappingEnd();
|
||||
_writer.WriteLine(";");
|
||||
return;
|
||||
}
|
||||
|
||||
// We aren't a bufferable attribute which means we have no Razor code in our value.
|
||||
// Therefore we can just use the "textValue" as the attribute value.
|
||||
RenderRawAttributeValue(textValue, attributeValueChunk.Start, attributeDescriptor);
|
||||
}
|
||||
|
||||
// End the assignment to the attribute.
|
||||
_writer.WriteLine(";");
|
||||
|
||||
// Execution contexts are a runtime feature.
|
||||
if (_designTimeMode)
|
||||
{
|
||||
|
|
@ -279,20 +298,23 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
|||
}
|
||||
|
||||
// We need to inform the context of the attribute value.
|
||||
_writer.WriteStartInstanceMethodInvocation(
|
||||
ExecutionContextVariableName,
|
||||
_tagHelperContext.ExecutionContextAddTagHelperAttributeMethodName);
|
||||
|
||||
_writer.WriteStringLiteral(attributeDescriptor.Name)
|
||||
.WriteParameterSeparator()
|
||||
.Write(valueAccessor)
|
||||
.WriteEndMethodInvocation();
|
||||
_writer
|
||||
.WriteStartInstanceMethodInvocation(
|
||||
ExecutionContextVariableName,
|
||||
_tagHelperContext.ExecutionContextAddTagHelperAttributeMethodName)
|
||||
.WriteStringLiteral(attributeDescriptor.Name)
|
||||
.WriteParameterSeparator()
|
||||
.Write(valueAccessor)
|
||||
.WriteEndMethodInvocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The attribute value has already been recorded, lets retrieve it from the stored value accessors.
|
||||
_writer.Write(htmlAttributeValues[attributeDescriptor.Name])
|
||||
.WriteLine(";");
|
||||
// The attribute value has already been recorded, lets retrieve it from the stored value
|
||||
// accessors.
|
||||
_writer
|
||||
.WriteStartAssignment(valueAccessor)
|
||||
.Write(htmlAttributeValues[attributeDescriptor.Name])
|
||||
.WriteLine(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -414,34 +436,30 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
|||
|
||||
private void RenderBufferedAttributeValue(TagHelperAttributeDescriptor attributeDescriptor)
|
||||
{
|
||||
// Pass complexValue: false because variable.ToString() replaces any original complexity in the expression.
|
||||
RenderAttributeValue(
|
||||
attributeDescriptor,
|
||||
valueRenderer: (writer) =>
|
||||
{
|
||||
RenderBufferedAttributeValueAccessor(writer);
|
||||
});
|
||||
},
|
||||
complexValue: false);
|
||||
}
|
||||
|
||||
private void RenderRawAttributeValue(string value,
|
||||
SourceLocation documentLocation,
|
||||
TagHelperAttributeDescriptor attributeDescriptor)
|
||||
private void RenderRawAttributeValue(
|
||||
Chunk attributeValueChunk,
|
||||
TagHelperAttributeDescriptor attributeDescriptor,
|
||||
bool isPlainTextValue)
|
||||
{
|
||||
RenderAttributeValue(
|
||||
attributeDescriptor,
|
||||
valueRenderer: (writer) =>
|
||||
{
|
||||
if (_context.Host.DesignTimeMode)
|
||||
{
|
||||
using (new CSharpLineMappingWriter(writer, documentLocation, value.Length))
|
||||
{
|
||||
writer.Write(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(value);
|
||||
}
|
||||
});
|
||||
var visitor =
|
||||
new CSharpTagHelperAttributeValueVisitor(writer, _context, attributeDescriptor.TypeName);
|
||||
visitor.Accept(attributeValueChunk);
|
||||
},
|
||||
complexValue: !isPlainTextValue);
|
||||
}
|
||||
|
||||
private void RenderQuotedAttributeValue(string value, TagHelperAttributeDescriptor attributeDescriptor)
|
||||
|
|
@ -451,7 +469,8 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
|||
valueRenderer: (writer) =>
|
||||
{
|
||||
writer.WriteStringLiteral(value);
|
||||
});
|
||||
},
|
||||
complexValue: false);
|
||||
}
|
||||
|
||||
private void BuildBufferedWritingScope(Chunk htmlAttributeChunk)
|
||||
|
|
@ -502,9 +521,15 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
|||
}
|
||||
|
||||
private void RenderAttributeValue(TagHelperAttributeDescriptor attributeDescriptor,
|
||||
Action<CSharpCodeWriter> valueRenderer)
|
||||
Action<CSharpCodeWriter> valueRenderer,
|
||||
bool complexValue)
|
||||
{
|
||||
AttributeValueCodeRenderer.RenderAttributeValue(attributeDescriptor, _writer, _context, valueRenderer);
|
||||
AttributeValueCodeRenderer.RenderAttributeValue(
|
||||
attributeDescriptor,
|
||||
_writer,
|
||||
_context,
|
||||
valueRenderer,
|
||||
complexValue);
|
||||
}
|
||||
|
||||
private void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Razor.Parser;
|
||||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="CodeVisitor{CSharpCodeWriter}"/> that writes code for a non-<see langword="string"/> tag helper
|
||||
/// bound attribute value.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Since attribute value is not written out as HTML, does not emit instrumentation. Further this
|
||||
/// <see cref="CodeVisitor{CSharpCodeWriter}"/> writes identical code at design- and runtime.
|
||||
/// </remarks>
|
||||
public class CSharpTagHelperAttributeValueVisitor : CodeVisitor<CSharpCodeWriter>
|
||||
{
|
||||
private string _attributeTypeName;
|
||||
private bool _firstChild;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CSharpTagHelperAttributeValueVisitor"/> class.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="CSharpCodeWriter"/> used to write code.</param>
|
||||
/// <param name="context">
|
||||
/// A <see cref="CodeBuilderContext"/> instance that contains information about the current code generation
|
||||
/// process.
|
||||
/// </param>
|
||||
/// <param name="attributeTypeName">
|
||||
/// Full name of the property <see cref="System.Type"/> for which this
|
||||
/// <see cref="CSharpTagHelperAttributeValueVisitor"/> is writing the value.
|
||||
/// </param>
|
||||
public CSharpTagHelperAttributeValueVisitor(
|
||||
CSharpCodeWriter writer,
|
||||
CodeBuilderContext context,
|
||||
string attributeTypeName)
|
||||
: base(writer, context)
|
||||
{
|
||||
_attributeTypeName = attributeTypeName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="ChunkBlock"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Tracks code mappings for all children while writing.
|
||||
/// </remarks>
|
||||
protected override void Visit(ChunkBlock chunk)
|
||||
{
|
||||
// Line mappings are captured in RenderCode(), not this method.
|
||||
_firstChild = true;
|
||||
Accept(chunk.Children);
|
||||
|
||||
if (_firstChild)
|
||||
{
|
||||
// Attribute value was empty.
|
||||
Context.ErrorSink.OnError(
|
||||
chunk.Association.Start,
|
||||
RazorResources.TagHelpers_AttributeExpressionRequired,
|
||||
chunk.Association.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="ExpressionBlockChunk"/> to render.</param>
|
||||
protected override void Visit(ExpressionBlockChunk chunk)
|
||||
{
|
||||
Accept(chunk.Children);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="ExpressionChunk"/> to render.</param>
|
||||
protected override void Visit(ExpressionChunk chunk)
|
||||
{
|
||||
RenderCode(chunk.Code, (Span)chunk.Association);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="LiteralChunk"/> to render.</param>
|
||||
protected override void Visit(LiteralChunk chunk)
|
||||
{
|
||||
RenderCode(chunk.Text, (Span)chunk.Association);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="ResolveUrlChunk"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Allowed to support future C# extensions. Likely "~/..." will lead to a C# compilation error but that is up
|
||||
/// to the compiler.
|
||||
/// </remarks>
|
||||
protected override void Visit(ResolveUrlChunk chunk)
|
||||
{
|
||||
RenderCode(chunk.Url, (Span)chunk.Association);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="SectionChunk"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Unconditionally adds a <see cref="RazorError"/> to inform user of unexpected <c>@section</c> directive.
|
||||
/// </remarks>
|
||||
protected override void Visit(SectionChunk chunk)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
chunk.Association.Start,
|
||||
RazorResources.FormatTagHelpers_Directives_NotSupported_InAttributes(
|
||||
SyntaxConstants.CSharp.SectionKeyword),
|
||||
chunk.Association.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="SetLayoutChunk"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Unconditionally adds a <see cref="RazorError"/> to inform user of unexpected <c>@layout</c> directive.
|
||||
/// </remarks>
|
||||
protected override void Visit(SetLayoutChunk chunk)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
chunk.Association.Start,
|
||||
RazorResources.FormatTagHelpers_Directives_NotSupported_InAttributes(
|
||||
SyntaxConstants.CSharp.LayoutKeyword),
|
||||
chunk.Association.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="StatementChunk"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Unconditionally adds a <see cref="RazorError"/> to inform user of unexpected code block.
|
||||
/// </remarks>
|
||||
protected override void Visit(StatementChunk chunk)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
chunk.Association.Start,
|
||||
RazorResources.TagHelpers_CodeBlocks_NotSupported_InAttributes,
|
||||
chunk.Association.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes code for the given <paramref name="chunk"/>.
|
||||
/// </summary>
|
||||
/// <param name="chunk">The <see cref="TemplateChunk"/> to render.</param>
|
||||
/// <remarks>
|
||||
/// Unconditionally adds a <see cref="RazorError"/> to inform user of unexpected template e.g.
|
||||
/// <c>@<p>paragraph@</p></c>.
|
||||
/// </remarks>
|
||||
protected override void Visit(TemplateChunk chunk)
|
||||
{
|
||||
Context.ErrorSink.OnError(
|
||||
chunk.Association.Start,
|
||||
RazorResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(_attributeTypeName),
|
||||
chunk.Association.Length);
|
||||
}
|
||||
|
||||
// Tracks the code mapping and writes code for a leaf node in the attribute value Chunk tree.
|
||||
private void RenderCode(string code, Span association)
|
||||
{
|
||||
_firstChild = false;
|
||||
using (new CSharpLineMappingWriter(Writer, association.Start, code.Length))
|
||||
{
|
||||
Writer.Write(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,6 +66,7 @@ namespace Microsoft.AspNet.Razor.Generator
|
|||
|
||||
attributes[attribute.Key] = new ChunkBlock
|
||||
{
|
||||
Association = first?.Association,
|
||||
Children = chunks,
|
||||
Start = first == null ? SourceLocation.Zero : first.Start
|
||||
};
|
||||
|
|
|
|||
|
|
@ -390,38 +390,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return GetString("ParseError_Unterminated_String_Literal");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unknown option: "{0}".
|
||||
/// </summary>
|
||||
internal static string ParseError_UnknownOption
|
||||
{
|
||||
get { return GetString("ParseError_UnknownOption"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unknown option: "{0}".
|
||||
/// </summary>
|
||||
internal static string FormatParseError_UnknownOption(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_UnknownOption"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The "{0}" block was not terminated. All "{0}" statements must be terminated with a matching "{1}".
|
||||
/// </summary>
|
||||
internal static string ParseError_BlockNotTerminated
|
||||
{
|
||||
get { return GetString("ParseError_BlockNotTerminated"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The "{0}" block was not terminated. All "{0}" statements must be terminated with a matching "{1}".
|
||||
/// </summary>
|
||||
internal static string FormatParseError_BlockNotTerminated(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_BlockNotTerminated"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// @section Header { ... }
|
||||
/// </summary>
|
||||
|
|
@ -454,22 +422,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return GetString("ParseError_TextTagCannotContainAttributes");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The "Imports" keyword must be followed by a namespace or a type alias on the same line.
|
||||
/// </summary>
|
||||
internal static string ParseError_NamespaceOrTypeAliasExpected
|
||||
{
|
||||
get { return GetString("ParseError_NamespaceOrTypeAliasExpected"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The "Imports" keyword must be followed by a namespace or a type alias on the same line.
|
||||
/// </summary>
|
||||
internal static string FormatParseError_NamespaceOrTypeAliasExpected()
|
||||
{
|
||||
return GetString("ParseError_NamespaceOrTypeAliasExpected");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between.
|
||||
/// </summary>
|
||||
|
|
@ -998,22 +950,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("TokenizerView_CannotPutBack"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unexpected "{0}"
|
||||
/// </summary>
|
||||
internal static string ParseError_Unexpected
|
||||
{
|
||||
get { return GetString("ParseError_Unexpected"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unexpected "{0}"
|
||||
/// </summary>
|
||||
internal static string FormatParseError_Unexpected(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("ParseError_Unexpected"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unexpected "{" after "@" character. Once inside the body of a code block (@if {}, @{}, etc.) you do not need to use "@{" to switch to code.
|
||||
/// </summary>
|
||||
|
|
@ -1142,38 +1078,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return GetString("Language_Does_Not_Support_RazorComment");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing value for session state directive.
|
||||
/// </summary>
|
||||
internal static string ParserEror_SessionDirectiveMissingValue
|
||||
{
|
||||
get { return GetString("ParserEror_SessionDirectiveMissingValue"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing value for session state directive.
|
||||
/// </summary>
|
||||
internal static string FormatParserEror_SessionDirectiveMissingValue()
|
||||
{
|
||||
return GetString("ParserEror_SessionDirectiveMissingValue");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot call CreateCodeWriter, a CodeWriter was not provided to the Create method
|
||||
/// </summary>
|
||||
internal static string CreateCodeWriter_NoCodeWriter
|
||||
{
|
||||
get { return GetString("CreateCodeWriter_NoCodeWriter"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cannot call CreateCodeWriter, a CodeWriter was not provided to the Create method
|
||||
/// </summary>
|
||||
internal static string FormatCreateCodeWriter_NoCodeWriter()
|
||||
{
|
||||
return GetString("CreateCodeWriter_NoCodeWriter");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [BG][{0}] Shutdown
|
||||
/// </summary>
|
||||
|
|
@ -1478,22 +1382,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return GetString("TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TagHelper attributes that do not expect strings must not have @ symbols within them. Found attribute '{0}' with an invalid value.
|
||||
/// </summary>
|
||||
internal static string TagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols
|
||||
{
|
||||
get { return GetString("TagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TagHelper attributes that do not expect strings must not have @ symbols within them. Found attribute '{0}' with an invalid value.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Directive '{0}' must have a value.
|
||||
/// </summary>
|
||||
|
|
@ -1542,22 +1430,6 @@ namespace Microsoft.AspNet.Razor
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpersParseTreeRewriter_FoundMalformedTagHelper"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing '{0}' from '{1}' tag helper.
|
||||
/// </summary>
|
||||
internal static string TagHelpersParseTreeRewriter_MissingValueFromTagHelper
|
||||
{
|
||||
get { return GetString("TagHelpersParseTreeRewriter_MissingValueFromTagHelper"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing '{0}' from '{1}' tag helper.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpersParseTreeRewriter_MissingValueFromTagHelper(object p0, object p1)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpersParseTreeRewriter_MissingValueFromTagHelper"), p0, p1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Missing close angle for tag helper '{0}'.
|
||||
/// </summary>
|
||||
|
|
@ -1590,6 +1462,74 @@ namespace Microsoft.AspNet.Razor
|
|||
return GetString("TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Non-string tag helper attribute values must not be empty. Add an expression to this attribute value.
|
||||
/// </summary>
|
||||
internal static string TagHelpers_AttributeExpressionRequired
|
||||
{
|
||||
get { return GetString("TagHelpers_AttributeExpressionRequired"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Non-string tag helper attribute values must not be empty. Add an expression to this attribute value.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpers_AttributeExpressionRequired()
|
||||
{
|
||||
return GetString("TagHelpers_AttributeExpressionRequired");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Code blocks (e.g. @{{var variable = 23;}}) must not appear in non-string tag helper attribute values.
|
||||
/// Already in an expression (code) context. If necessary an explicit expression (e.g. @(@readonly)) may be used.
|
||||
/// </summary>
|
||||
internal static string TagHelpers_CodeBlocks_NotSupported_InAttributes
|
||||
{
|
||||
get { return GetString("TagHelpers_CodeBlocks_NotSupported_InAttributes"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Code blocks (e.g. @{{var variable = 23;}}) must not appear in non-string tag helper attribute values.
|
||||
/// Already in an expression (code) context. If necessary an explicit expression (e.g. @(@readonly)) may be used.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpers_CodeBlocks_NotSupported_InAttributes()
|
||||
{
|
||||
return GetString("TagHelpers_CodeBlocks_NotSupported_InAttributes");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// @'{0}' directives must not appear in non-string tag helper attribute values.
|
||||
/// </summary>
|
||||
internal static string TagHelpers_Directives_NotSupported_InAttributes
|
||||
{
|
||||
get { return GetString("TagHelpers_Directives_NotSupported_InAttributes"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// @'{0}' directives must not appear in non-string tag helper attribute values.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpers_Directives_NotSupported_InAttributes(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpers_Directives_NotSupported_InAttributes"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inline markup blocks (e.g. @<p>content</p>) must not appear in non-string tag helper attribute values.
|
||||
/// Expected a '{0}' attribute value, not a string.
|
||||
/// </summary>
|
||||
internal static string TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes
|
||||
{
|
||||
get { return GetString("TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inline markup blocks (e.g. @<p>content</p>) must not appear in non-string tag helper attribute values.
|
||||
/// Expected a '{0}' attribute value, not a string.
|
||||
/// </summary>
|
||||
internal static string FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes"), p0);
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -206,12 +206,6 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="ParseError_Unterminated_String_Literal" xml:space="preserve">
|
||||
<value>Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.</value>
|
||||
</data>
|
||||
<data name="ParseError_UnknownOption" xml:space="preserve">
|
||||
<value>Unknown option: "{0}".</value>
|
||||
</data>
|
||||
<data name="ParseError_BlockNotTerminated" xml:space="preserve">
|
||||
<value>The "{0}" block was not terminated. All "{0}" statements must be terminated with a matching "{1}".</value>
|
||||
</data>
|
||||
<data name="SectionExample_CS" xml:space="preserve">
|
||||
<value>@section Header { ... }</value>
|
||||
<comment>In CSHTML, the @section keyword is case-sensitive and lowercase (as with all C# keywords)</comment>
|
||||
|
|
@ -219,9 +213,6 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="ParseError_TextTagCannotContainAttributes" xml:space="preserve">
|
||||
<value>"<text>" and "</text>" tags cannot contain attributes.</value>
|
||||
</data>
|
||||
<data name="ParseError_NamespaceOrTypeAliasExpected" xml:space="preserve">
|
||||
<value>The "Imports" keyword must be followed by a namespace or a type alias on the same line.</value>
|
||||
</data>
|
||||
<data name="ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS" xml:space="preserve">
|
||||
<value>A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between.</value>
|
||||
</data>
|
||||
|
|
@ -321,9 +312,6 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="TokenizerView_CannotPutBack" xml:space="preserve">
|
||||
<value>In order to put a symbol back, it must have been the symbol which ended at the current position. The specified symbol ends at {0}, but the current position is {1}</value>
|
||||
</data>
|
||||
<data name="ParseError_Unexpected" xml:space="preserve">
|
||||
<value>Unexpected "{0}"</value>
|
||||
</data>
|
||||
<data name="ParseError_Unexpected_Nested_CodeBlock" xml:space="preserve">
|
||||
<value>Unexpected "{" after "@" character. Once inside the body of a code block (@if {}, @{}, etc.) you do not need to use "@{" to switch to code.</value>
|
||||
</data>
|
||||
|
|
@ -348,13 +336,6 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="Language_Does_Not_Support_RazorComment" xml:space="preserve">
|
||||
<value>Cannot use built-in RazorComment handler, language characteristics does not define the CommentStart, CommentStar and CommentBody known symbol types or parser does not override TokenizerBackedParser.OutputSpanBeforeRazorComment</value>
|
||||
</data>
|
||||
<data name="ParserEror_SessionDirectiveMissingValue" xml:space="preserve">
|
||||
<value>Missing value for session state directive.</value>
|
||||
</data>
|
||||
<data name="CreateCodeWriter_NoCodeWriter" xml:space="preserve">
|
||||
<value>Cannot call CreateCodeWriter, a CodeWriter was not provided to the Create method</value>
|
||||
<comment>This error should not be seen by users, it should only appear to internal developers, but I'm putting it in resources just in case</comment>
|
||||
</data>
|
||||
<data name="Trace_BackgroundThreadShutdown" xml:space="preserve">
|
||||
<value>[BG][{0}] Shutdown</value>
|
||||
</data>
|
||||
|
|
@ -412,9 +393,6 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="TagHelpers_TagHelperCodeGeneartorMustBeAssociatedWithATagHelperBlock" xml:space="preserve">
|
||||
<value>A TagHelperCodeGenerator must only be used with TagHelperBlocks.</value>
|
||||
</data>
|
||||
<data name="TagHelpers_AttributesThatAreNotStringsMustNotContainAtSymbols" xml:space="preserve">
|
||||
<value>TagHelper attributes that do not expect strings must not have @ symbols within them. Found attribute '{0}' with an invalid value.</value>
|
||||
</data>
|
||||
<data name="ParseError_DirectiveMustHaveValue" xml:space="preserve">
|
||||
<value>Directive '{0}' must have a value.</value>
|
||||
</data>
|
||||
|
|
@ -424,13 +402,24 @@ Instead, wrap the contents of the block in "{{}}":
|
|||
<data name="TagHelpersParseTreeRewriter_FoundMalformedTagHelper" xml:space="preserve">
|
||||
<value>Found a malformed '{0}' tag helper. Tag helpers must have a start and end tag or be self closing.</value>
|
||||
</data>
|
||||
<data name="TagHelpersParseTreeRewriter_MissingValueFromTagHelper" xml:space="preserve">
|
||||
<value>Missing '{0}' from '{1}' tag helper.</value>
|
||||
</data>
|
||||
<data name="TagHelpersParseTreeRewriter_MissingCloseAngle" xml:space="preserve">
|
||||
<value>Missing close angle for tag helper '{0}'.</value>
|
||||
</data>
|
||||
<data name="TagHelperBlockRewriter_TagHelperAttributesMustBeWelformed" xml:space="preserve">
|
||||
<value>TagHelper attributes must be welformed.</value>
|
||||
</data>
|
||||
<data name="TagHelpers_AttributeExpressionRequired" xml:space="preserve">
|
||||
<value>Non-string tag helper attribute values must not be empty. Add an expression to this attribute value.</value>
|
||||
</data>
|
||||
<data name="TagHelpers_CodeBlocks_NotSupported_InAttributes" xml:space="preserve">
|
||||
<value>Code blocks (e.g. @{{var variable = 23;}}) must not appear in non-string tag helper attribute values.
|
||||
Already in an expression (code) context. If necessary an explicit expression (e.g. @(@readonly)) may be used.</value>
|
||||
</data>
|
||||
<data name="TagHelpers_Directives_NotSupported_InAttributes" xml:space="preserve">
|
||||
<value>@'{0}' directives must not appear in non-string tag helper attribute values.</value>
|
||||
</data>
|
||||
<data name="TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes" xml:space="preserve">
|
||||
<value>Inline markup blocks (e.g. @<p>content</p>) must not appear in non-string tag helper attribute values.
|
||||
Expected a '{0}' attribute value, not a string.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -16,15 +16,25 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
/// Called during Razor's code generation process to generate code that instantiates the value of the tag
|
||||
/// helper's property. Last value written should not be or end with a semicolon.
|
||||
/// </summary>
|
||||
/// <param name="attributeDescriptor">The <see cref="TagHelperAttributeDescriptor"/> to generate code for.</param>
|
||||
/// <param name="attributeDescriptor">
|
||||
/// The <see cref="TagHelperAttributeDescriptor"/> to generate code for.
|
||||
/// </param>
|
||||
/// <param name="writer">The <see cref="CSharpCodeWriter"/> that's used to write code.</param>
|
||||
/// <param name="context">A <see cref="CodeGeneratorContext"/> instance that contains information about
|
||||
/// the current code generation process.</param>
|
||||
/// <param name="renderAttributeValue"><see cref="Action"/> that renders the raw value of the HTML attribute.</param>
|
||||
/// <param name="renderAttributeValue">
|
||||
/// <see cref="Action"/> that renders the raw value of the HTML attribute.
|
||||
/// </param>
|
||||
/// <param name="complexValue">
|
||||
/// Indicates whether or not the source attribute value contains more than simple text. <c>false</c> for plain
|
||||
/// C# expressions e.g. <c>"PropertyName"</c>. <c>true</c> if the attribute value contain at least one in-line
|
||||
/// Razor construct e.g. <c>"@(@readonly)"</c>.
|
||||
/// </param>
|
||||
public virtual void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeDescriptor,
|
||||
[NotNull] CSharpCodeWriter writer,
|
||||
[NotNull] CodeBuilderContext context,
|
||||
[NotNull] Action<CSharpCodeWriter> renderAttributeValue)
|
||||
[NotNull] Action<CSharpCodeWriter> renderAttributeValue,
|
||||
bool complexValue)
|
||||
{
|
||||
renderAttributeValue(writer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,10 +177,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
contentLength: 11),
|
||||
BuildLineMapping(documentAbsoluteIndex: 57,
|
||||
documentLineIndex: 2,
|
||||
documentCharacterOffsetIndex: 28,
|
||||
generatedAbsoluteIndex: 927,
|
||||
generatedLineIndex: 33,
|
||||
generatedCharacterOffsetIndex: 31,
|
||||
generatedAbsoluteIndex: 958,
|
||||
generatedLineIndex: 34,
|
||||
characterOffsetIndex: 28,
|
||||
contentLength: 4)
|
||||
}
|
||||
},
|
||||
|
|
@ -198,10 +197,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
contentLength: 11),
|
||||
BuildLineMapping(documentAbsoluteIndex: 189,
|
||||
documentLineIndex: 6,
|
||||
documentCharacterOffsetIndex: 40,
|
||||
generatedAbsoluteIndex: 1599,
|
||||
generatedLineIndex: 44,
|
||||
generatedCharacterOffsetIndex: 40,
|
||||
generatedAbsoluteIndex: 1633,
|
||||
generatedLineIndex: 45,
|
||||
characterOffsetIndex: 40,
|
||||
contentLength: 4)
|
||||
}
|
||||
},
|
||||
|
|
@ -232,13 +230,27 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
BuildLineMapping(218, 9, 13, 1356, 56, 12, 27),
|
||||
BuildLineMapping(346, 12, 1754, 68, 0, 48),
|
||||
BuildLineMapping(440, 15, 46, 2004, 78, 6, 8),
|
||||
BuildLineMapping(457, 15, 63, 2267, 85, 40, 4),
|
||||
BuildLineMapping(501, 16, 31, 2384, 88, 6, 30),
|
||||
BuildLineMapping(568, 17, 30, 2733, 97, 0, 10),
|
||||
BuildLineMapping(601, 17, 63, 2815, 103, 0, 8),
|
||||
BuildLineMapping(632, 17, 94, 2895, 109, 0, 1),
|
||||
BuildLineMapping(639, 18, 3149, 118, 0, 15),
|
||||
BuildLineMapping(680, 21, 3234, 124, 0, 1)
|
||||
BuildLineMapping(457, 15, 2327, 86, 63, 4),
|
||||
BuildLineMapping(501, 16, 31, 2475, 92, 6, 30),
|
||||
BuildLineMapping(568, 17, 30, 2824, 101, 0, 10),
|
||||
BuildLineMapping(601, 17, 63, 2906, 107, 0, 8),
|
||||
BuildLineMapping(632, 17, 94, 2986, 113, 0, 1),
|
||||
BuildLineMapping(639, 18, 3240, 122, 0, 15),
|
||||
BuildLineMapping(685, 20, 17, 3403, 129, 19, 23),
|
||||
BuildLineMapping(708, 20, 40, 3426, 129, 42, 7),
|
||||
BuildLineMapping(719, 21, 3504, 134, 0, 12),
|
||||
BuildLineMapping(733, 21, 3602, 140, 14, 21),
|
||||
BuildLineMapping(787, 22, 30, 3859, 148, 28, 7),
|
||||
BuildLineMapping(831, 24, 16, 4015, 154, 19, 8),
|
||||
BuildLineMapping(840, 24, 25, 4023, 154, 27, 23),
|
||||
BuildLineMapping(897, 25, 30, 4281, 161, 28, 30),
|
||||
BuildLineMapping(964, 27, 16, 4460, 167, 19, 30),
|
||||
BuildLineMapping(1026, 28, 4725, 174, 28, 30),
|
||||
BuildLineMapping(1094, 30, 18, 4904, 180, 19, 29),
|
||||
BuildLineMapping(1156, 31, 5168, 187, 28, 3),
|
||||
BuildLineMapping(1161, 31, 33, 5171, 187, 31, 27),
|
||||
BuildLineMapping(1189, 31, 61, 5198, 187, 58, 10),
|
||||
BuildLineMapping(1231, 34, 5279, 192, 0, 1),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -88,11 +88,12 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeInfo,
|
||||
[NotNull] CSharpCodeWriter writer,
|
||||
[NotNull] CodeBuilderContext context,
|
||||
[NotNull] Action<CSharpCodeWriter> renderAttributeValue)
|
||||
[NotNull] Action<CSharpCodeWriter> renderAttributeValue,
|
||||
bool complexValue)
|
||||
{
|
||||
writer.Write("**From custom attribute code renderer**: ");
|
||||
|
||||
base.RenderAttributeValue(attributeInfo, writer, context, renderAttributeValue);
|
||||
base.RenderAttributeValue(attributeInfo, writer, context, renderAttributeValue, complexValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,11 @@ namespace TestOutput
|
|||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 7 "BasicTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = **From custom attribute code renderer**: true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
|
|
|
|||
|
|
@ -42,7 +42,11 @@ namespace TestOutput
|
|||
__InputTagHelper.Type = "checkbox";
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 7 "BasicTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,11 @@ namespace TestOutput
|
|||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
#line 7 "BasicTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
|
|
|
|||
|
|
@ -83,7 +83,11 @@ __o = checkbox;
|
|||
__InputTagHelper.Type = string.Empty;
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
__InputTagHelper2.Checked = true;
|
||||
#line 16 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
#line 17 "ComplexTagHelpers.cshtml"
|
||||
__o = true ? "checkbox" : "anything";
|
||||
|
|
@ -121,7 +125,71 @@ if(true) {
|
|||
#line default
|
||||
#line hidden
|
||||
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
#line 21 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 22 "ComplexTagHelpers.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 22 "ComplexTagHelpers.cshtml"
|
||||
var @object = false;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
#line 23 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = @object;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
#line 25 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = -1970 + DateTimeOffset.Now.Year;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
#line 26 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
#line 28 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
#line 29 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
#line 31 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = "My age is this long.".Length;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
#line 32 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014 ;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
#line 35 "ComplexTagHelpers.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#pragma checksum "ComplexTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "cce31144cd1c3c35d241b49e41c4fc04ff044565"
|
||||
#pragma checksum "ComplexTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "7158abc69d261099393d49d82670ec64a94d9770"
|
||||
namespace TestOutput
|
||||
{
|
||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||
|
|
@ -134,7 +134,11 @@ Write(checkbox);
|
|||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||
__InputTagHelper2.Checked = true;
|
||||
#line 16 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = true;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
|
|
@ -215,10 +219,173 @@ if(true) {
|
|||
Instrumentation.EndContext();
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(666, 14, true);
|
||||
WriteLiteral("\r\n </div>\r\n");
|
||||
Instrumentation.BeginContext(666, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test");
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
#line 21 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
Instrumentation.BeginContext(717, 2, true);
|
||||
WriteLiteral("\r\n");
|
||||
Instrumentation.EndContext();
|
||||
#line 22 "ComplexTagHelpers.cshtml"
|
||||
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
#line 22 "ComplexTagHelpers.cshtml"
|
||||
var @object = false;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
|
||||
Instrumentation.BeginContext(755, 14, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test");
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
#line 23 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = @object;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(799, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(813, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test");
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
#line 25 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = -1970 + DateTimeOffset.Now.Year;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
Instrumentation.BeginContext(865, 14, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test");
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
#line 26 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(932, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(946, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test");
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
#line 28 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
Instrumentation.BeginContext(996, 14, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test");
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
#line 29 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(1060, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(1074, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test");
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
#line 31 "ComplexTagHelpers.cshtml"
|
||||
__PTagHelper.Age = "My age is this long.".Length;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
Instrumentation.BeginContext(1126, 14, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test");
|
||||
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||
#line 32 "ComplexTagHelpers.cshtml"
|
||||
__InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014 ;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(1203, 10, true);
|
||||
WriteLiteral("\r\n ");
|
||||
Instrumentation.EndContext();
|
||||
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
Instrumentation.BeginContext(1217, 14, true);
|
||||
WriteLiteral("\r\n </div>\r\n");
|
||||
Instrumentation.EndContext();
|
||||
#line 35 "ComplexTagHelpers.cshtml"
|
||||
}
|
||||
|
||||
#line default
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ namespace TestOutput
|
|||
public override async Task ExecuteAsync()
|
||||
{
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__PTagHelper.Age = 1337;
|
||||
#line 3 "SingleTagHelper.cshtml"
|
||||
__PTagHelper.Age = 1337;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ namespace TestOutput
|
|||
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", "test");
|
||||
__PTagHelper = CreateTagHelper<PTagHelper>();
|
||||
__tagHelperExecutionContext.Add(__PTagHelper);
|
||||
__PTagHelper.Age = 1337;
|
||||
#line 3 "SingleTagHelper.cshtml"
|
||||
__PTagHelper.Age = 1337;
|
||||
|
||||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age);
|
||||
__tagHelperExecutionContext.AddHtmlAttribute("class", "Hello World");
|
||||
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||
|
|
|
|||
|
|
@ -18,5 +18,18 @@
|
|||
<input type='@if(true) { <text>checkbox</text> } else { <text>anything</text> }' />
|
||||
}
|
||||
</p>
|
||||
<p age="@DateTimeOffset.Now.Year - 1970">
|
||||
@{ var @object = false;}
|
||||
<input checked="@(@object)" />
|
||||
</p>
|
||||
<p age="-1970 + @DateTimeOffset.Now.Year">
|
||||
<input checked="@(DateTimeOffset.Now.Year > 2014)" />
|
||||
</p>
|
||||
<p age="DateTimeOffset.Now.Year - 1970">
|
||||
<input checked="DateTimeOffset.Now.Year > 2014" />
|
||||
</p>
|
||||
<p age="@("My age is this long.".Length)">
|
||||
<input checked=" @( DateTimeOffset.Now.Year ) > 2014 " />
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
Loading…
Reference in New Issue