diff --git a/src/Microsoft.AspNet.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs b/src/Microsoft.AspNet.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs index 513acad2cc..a6d6b27943 100644 --- a/src/Microsoft.AspNet.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs +++ b/src/Microsoft.AspNet.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs @@ -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 { diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ComplexTagHelpers.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ComplexTagHelpers.cs index c37a5fb3bc..3f4d3526e7 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ComplexTagHelpers.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ComplexTagHelpers.cs @@ -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); diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ConditionalAttributes.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ConditionalAttributes.cs index 6dcc7c85de..c48e2cb35c 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ConditionalAttributes.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/Output/ConditionalAttributes.cs @@ -26,34 +26,54 @@ namespace TestOutput WriteLiteral(" \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n