Add line pragmas to dynamic attributes.

- This enables debugging and proper error reporting for dynamic attributes. Without the pragmas errors would showcase generated Razor C# instead of their corresponding .cshtml files.
- Did not have to do any `TagHelper` specific changes since they utilize the same core attribute rendering logic.
- Updated generated C# files for tests.

#569
This commit is contained in:
N. Taylor Mullen 2015-10-16 09:41:12 -07:00
parent ed617d17e9
commit 2d4092ca32
6 changed files with 106 additions and 19 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks;
@ -181,6 +182,17 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
var currentRenderingMode = Context.ExpressionRenderingMode;
var currentTargetWriterName = Context.TargetWriterName;
CSharpLineMappingWriter lineMappingWriter = null;
var code = chunk.Children.FirstOrDefault();
if (code is ExpressionChunk || code is ExpressionBlockChunk)
{
// We only want to render the #line pragma if the attribute value will be in-lined.
// Ex: WriteAttributeValue("", 0, DateTime.Now, 0, 0, false)
// For non-inlined scenarios: WriteAttributeValue("", 0, (_) => ..., 0, 0, false)
// the line pragma will be generated inside the lambda.
lineMappingWriter = new CSharpLineMappingWriter(Writer, chunk.Start, Context.SourceFile);
}
if (!string.IsNullOrEmpty(currentTargetWriterName))
{
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteAttributeValueToMethodName)
@ -194,9 +206,10 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
Context.TargetWriterName = ValueWriterName;
var code = chunk.Children.FirstOrDefault();
if (code is ExpressionChunk || code is ExpressionBlockChunk)
{
Debug.Assert(lineMappingWriter != null);
Writer
.WriteLocationTaggedString(chunk.Prefix)
.WriteParameterSeparator();
@ -213,6 +226,8 @@ namespace Microsoft.AspNet.Razor.CodeGenerators.Visitors
.WriteParameterSeparator()
.WriteBooleanLiteral(value: false)
.WriteEndMethodInvocation();
lineMappingWriter.Dispose();
}
else
{

View File

@ -242,7 +242,11 @@ if(true) {
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "time", 3);
AddHtmlAttributeValue("", 148, "Current", 148, 7, true);
AddHtmlAttributeValue(" ", 155, "Time:", 156, 6, true);
AddHtmlAttributeValue(" ", 161, DateTime.Now, 162, 14, false);
#line 8 "ComplexTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 161, DateTime.Now, 162, 14, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(139, 529, false);

View File

@ -26,34 +26,54 @@ namespace TestOutput
WriteLiteral(" <a href=\"Foo\" />\r\n <p");
Instrumentation.EndContext();
BeginWriteAttribute("class", " class=\"", 74, "\"", 86, 1);
WriteAttributeValue("", 82, cls, 82, 4, false);
#line 5 "ConditionalAttributes.cshtml"
WriteAttributeValue("", 82, cls, 82, 4, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(87, 11, true);
WriteLiteral(" />\r\n <p");
Instrumentation.EndContext();
BeginWriteAttribute("class", " class=\"", 98, "\"", 114, 2);
WriteAttributeValue("", 106, "foo", 106, 3, true);
WriteAttributeValue(" ", 109, cls, 110, 5, false);
#line 6 "ConditionalAttributes.cshtml"
WriteAttributeValue(" ", 109, cls, 110, 5, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(115, 11, true);
WriteLiteral(" />\r\n <p");
Instrumentation.EndContext();
BeginWriteAttribute("class", " class=\"", 126, "\"", 142, 2);
WriteAttributeValue("", 134, cls, 134, 4, false);
#line 7 "ConditionalAttributes.cshtml"
WriteAttributeValue("", 134, cls, 134, 4, false);
#line default
#line hidden
WriteAttributeValue(" ", 138, "foo", 139, 4, true);
EndWriteAttribute();
Instrumentation.BeginContext(143, 31, true);
WriteLiteral(" />\r\n <input type=\"checkbox\"");
Instrumentation.EndContext();
BeginWriteAttribute("checked", " checked=\"", 174, "\"", 187, 1);
WriteAttributeValue("", 184, ch, 184, 3, false);
#line 8 "ConditionalAttributes.cshtml"
WriteAttributeValue("", 184, ch, 184, 3, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(188, 31, true);
WriteLiteral(" />\r\n <input type=\"checkbox\"");
Instrumentation.EndContext();
BeginWriteAttribute("checked", " checked=\"", 219, "\"", 236, 2);
WriteAttributeValue("", 229, "foo", 229, 3, true);
WriteAttributeValue(" ", 232, ch, 233, 4, false);
#line 9 "ConditionalAttributes.cshtml"
WriteAttributeValue(" ", 232, ch, 233, 4, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(237, 11, true);
WriteLiteral(" />\r\n <p");
@ -86,13 +106,21 @@ WriteTo(__razor_attribute_value_writer, cls);
WriteLiteral(" />\r\n <a href=\"~/Foo\" />\r\n <script");
Instrumentation.EndContext();
BeginWriteAttribute("src", " src=\"", 322, "\"", 373, 1);
WriteAttributeValue("", 328, Url.Content("~/Scripts/jquery-1.6.2.min.js"), 328, 45, false);
#line 12 "ConditionalAttributes.cshtml"
WriteAttributeValue("", 328, Url.Content("~/Scripts/jquery-1.6.2.min.js"), 328, 45, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(374, 46, true);
WriteLiteral(" type=\"text/javascript\"></script>\r\n <script");
Instrumentation.EndContext();
BeginWriteAttribute("src", " src=\"", 420, "\"", 487, 1);
WriteAttributeValue("", 426, Url.Content("~/Scripts/modernizr-2.0.6-development-only.js"), 426, 61, false);
#line 13 "ConditionalAttributes.cshtml"
WriteAttributeValue("", 426, Url.Content("~/Scripts/modernizr-2.0.6-development-only.js"), 426, 61, false);
#line default
#line hidden
EndWriteAttribute();
Instrumentation.BeginContext(488, 152, true);
WriteLiteral(" type=\"text/javascript\"></script>\r\n <script src=\"http://ajax.aspnetcdn.com/aja" +

View File

@ -34,7 +34,11 @@ namespace TestOutput
__tagHelperExecutionContext.Add(__InputTagHelper);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 2);
AddHtmlAttributeValue("", 51, "prefix", 51, 6, true);
AddHtmlAttributeValue(" ", 57, DateTime.Now, 58, 14, false);
#line 3 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 57, DateTime.Now, 58, 14, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(35, 40, false);
@ -113,7 +117,11 @@ WriteLiteral(DateTime.Now);
__tagHelperExecutionContext.AddTagHelperAttribute("bound", __InputTagHelper.Bound);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 3);
AddHtmlAttributeValue("", 206, "prefix", 206, 6, true);
AddHtmlAttributeValue(" ", 212, DateTime.Now, 213, 14, false);
#line 7 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 212, DateTime.Now, 213, 14, false);
#line default
#line hidden
AddHtmlAttributeValue(" ", 226, "suffix", 227, 7, true);
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
@ -174,7 +182,11 @@ WriteLiteral(int.MaxValue);
__InputTagHelper.Bound = __tagHelperStringValueBuffer.GetContent(HtmlEncoder);
__tagHelperExecutionContext.AddTagHelperAttribute("bound", __InputTagHelper.Bound);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 3);
AddHtmlAttributeValue("", 347, long.MinValue, 347, 14, false);
#line 10 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue("", 347, long.MinValue, 347, 14, false);
#line default
#line hidden
AddHtmlAttributeValue(" ", 361, new Template((__razor_attribute_value_writer) => {
#line 10 "DynamicAttributeTagHelpers.cshtml"
if (true) {
@ -210,7 +222,11 @@ WriteTo(__razor_attribute_value_writer, false);
}
), 362, 45, false);
AddHtmlAttributeValue(" ", 406, int.MaxValue, 407, 14, false);
#line 10 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 406, int.MaxValue, 407, 14, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(241, 183, false);
@ -226,11 +242,23 @@ WriteTo(__razor_attribute_value_writer, false);
__InputTagHelper = CreateTagHelper<InputTagHelper>();
__tagHelperExecutionContext.Add(__InputTagHelper);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 5);
AddHtmlAttributeValue("", 444, long.MinValue, 444, 14, false);
AddHtmlAttributeValue(" ", 458, DateTime.Now, 459, 14, false);
#line 12 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue("", 444, long.MinValue, 444, 14, false);
#line default
#line hidden
#line 12 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 458, DateTime.Now, 459, 14, false);
#line default
#line hidden
AddHtmlAttributeValue(" ", 472, "static", 473, 7, true);
AddHtmlAttributeValue(" ", 479, "content", 483, 11, true);
AddHtmlAttributeValue(" ", 490, int.MaxValue, 491, 14, false);
#line 12 "DynamicAttributeTagHelpers.cshtml"
AddHtmlAttributeValue(" ", 490, int.MaxValue, 491, 14, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(428, 80, false);

View File

@ -86,7 +86,11 @@ WriteLiteral(DateTime.Now);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unboundproperty", 3);
AddHtmlAttributeValue("", 188, "Current", 188, 7, true);
AddHtmlAttributeValue(" ", 195, "Time:", 196, 6, true);
AddHtmlAttributeValue(" ", 201, DateTime.Now, 202, 14, false);
#line 9 "TagHelpersInSection.cshtml"
AddHtmlAttributeValue(" ", 201, DateTime.Now, 202, 14, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
Instrumentation.BeginContext(114, 245, false);

View File

@ -68,7 +68,11 @@ namespace TestOutput
__PTagHelper = CreateTagHelper<PTagHelper>();
__tagHelperExecutionContext.Add(__PTagHelper);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 1);
AddHtmlAttributeValue("", 155, @class, 155, 9, false);
#line 8 "TransitionsInTagHelperAttributes.cshtml"
AddHtmlAttributeValue("", 155, @class, 155, 9, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
#line 8 "TransitionsInTagHelperAttributes.cshtml"
__PTagHelper.Age = 42;
@ -151,7 +155,11 @@ namespace TestOutput
__tagHelperExecutionContext.Add(__PTagHelper);
BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 2);
AddHtmlAttributeValue("", 298, "custom-", 298, 7, true);
AddHtmlAttributeValue("", 305, @class, 305, 9, false);
#line 12 "TransitionsInTagHelperAttributes.cshtml"
AddHtmlAttributeValue("", 305, @class, 305, 9, false);
#line default
#line hidden
EndAddHtmlAttributeValues(__tagHelperExecutionContext);
#line 12 "TransitionsInTagHelperAttributes.cshtml"
__PTagHelper.Age = 4 * @(@int + 2);