diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeWriter.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeWriter.cs index 4cd4a3ce25..4242e1228b 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeWriter.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpCodeWriter.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using Microsoft.AspNet.Razor.Parser.SyntaxTree; using Microsoft.AspNet.Razor.Text; namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp @@ -144,7 +145,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { Write(String.Format("using {0}", name)); - if(endLine) + if (endLine) { WriteLine(";"); } @@ -353,35 +354,35 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { switch (literal[i]) { - case '\r': - Write("\\r"); - break; - case '\t': - Write("\\t"); - break; - case '\"': - Write("\\\""); - break; - case '\'': - Write("\\\'"); - break; - case '\\': - Write("\\\\"); - break; - case '\0': - Write("\\\0"); - break; - case '\n': - Write("\\n"); - break; - case '\u2028': - case '\u2029': - Write("\\u"); - Write(((int)literal[i]).ToString("X4", CultureInfo.InvariantCulture)); - break; - default: - Write(literal[i].ToString()); - break; + case '\r': + Write("\\r"); + break; + case '\t': + Write("\\t"); + break; + case '\"': + Write("\\\""); + break; + case '\'': + Write("\\\'"); + break; + case '\\': + Write("\\\\"); + break; + case '\0': + Write("\\\0"); + break; + case '\n': + Write("\\n"); + break; + case '\u2028': + case '\u2029': + Write("\\u"); + Write(((int)literal[i]).ToString("X4", CultureInfo.InvariantCulture)); + break; + default: + Write(literal[i].ToString()); + break; } if (i > 0 && i % 80 == 0) { @@ -403,5 +404,21 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp } Write("\""); } + + public void WriteStartInstrumentationContext(CodeGeneratorContext context, SyntaxTreeNode syntaxNode, bool isLiteral) + { + WriteStartMethodInvocation(context.Host.GeneratedClassContext.BeginContextMethodName); + Write(syntaxNode.Start.AbsoluteIndex.ToString(CultureInfo.InvariantCulture)); + WriteParameterSeparator(); + Write(syntaxNode.Length.ToString(CultureInfo.InvariantCulture)); + WriteParameterSeparator(); + Write(isLiteral ? "true" : "false"); + WriteEndMethodInvocation(); + } + + public void WriteEndInstrumentationContext(CodeGeneratorContext context) + { + WriteMethodInvocation(context.Host.GeneratedClassContext.EndContextMethodName); + } } } diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpCodeVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpCodeVisitor.cs index 7ab0992a7f..ef32591f24 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpCodeVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpCodeVisitor.cs @@ -59,7 +59,14 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp return; } - // TODO: Add instrumentation + var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); + + if (generateInstrumentation) + { + // Add a non-literal context call (non-literal because the expanded URL will not match the source + // character-by-character) + Writer.WriteStartInstrumentationContext(Context, chunk.Association, isLiteral: false); + } if (!String.IsNullOrEmpty(chunk.Url) && !Context.Host.DesignTimeMode) { @@ -86,6 +93,11 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp Writer.WriteEndMethodInvocation(); } } + + if (generateInstrumentation) + { + Writer.WriteEndInstrumentationContext(Context); + } } protected override void Visit(LiteralChunk chunk) @@ -95,7 +107,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp return; } - // TODO: Add instrumentation + if (Context.Host.EnableInstrumentation) + { + Writer.WriteStartInstrumentationContext(Context, chunk.Association, isLiteral: true); + } if (!String.IsNullOrEmpty(chunk.Text) && !Context.Host.DesignTimeMode) { @@ -114,13 +129,14 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp .WriteEndMethodInvocation(); } - // TODO: Add instrumentation + if (Context.Host.EnableInstrumentation) + { + Writer.WriteEndInstrumentationContext(Context); + } } protected override void Visit(ExpressionBlockChunk chunk) { - // TODO: Handle instrumentation - if (Context.Host.DesignTimeMode) { RenderDesignTimeExpressionBlockChunk(chunk); @@ -280,21 +296,19 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp var currentTargetWriterName = Context.TargetWriterName; Context.TargetWriterName = TemplateWriterName; - + using (Writer.BuildLambda(endLine: false, parameterNames: TemplateWriterName)) { Accept(chunk.Children); } Context.TargetWriterName = currentTargetWriterName; - + Writer.WriteEndMethodInvocation(endLine: false); Writer.WriteEndMethodInvocation(); } public void RenderDesignTimeExpressionBlockChunk(ExpressionBlockChunk chunk) { - // TODO: Handle instrumentation - var firstChild = (ExpressionChunk)chunk.Children.FirstOrDefault(); if (firstChild != null) @@ -329,7 +343,28 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) { - // TODO: Handle instrumentation + var generateInstrumentation = ShouldGenerateInstrumentationForExpressions(); + Span contentSpan = null; + + if (generateInstrumentation) + { + // For expression chunks, such as @value, @(value) etc, pick the first Code or Markup span + // from the expression (in this case "value") and use that to calculate the length. This works + // accurately for most parts. The scenarios that don't work are + // (a) Expressions with inline comments (e.g. @(a @* comment *@ b)) - these have multiple code spans + // (b) Expressions with inline templates (e.g. @Foo(@
Hello world
)). + // Tracked via https://github.com/aspnet/Razor/issues/153 + + var block = (Block)chunk.Association; + contentSpan = block.Children + .OfType() + .FirstOrDefault(s => s.Kind == SpanKind.Code || s.Kind == SpanKind.Markup); + + if (contentSpan != null) + { + Writer.WriteStartInstrumentationContext(Context, contentSpan, isLiteral: false); + } + } if (Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode) { @@ -353,6 +388,11 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp Writer.WriteEndMethodInvocation() .WriteLine(); } + + if (contentSpan != null) + { + Writer.WriteEndInstrumentationContext(Context); + } } public void CreateExpressionCodeMapping(string code, Chunk chunk) @@ -385,5 +425,13 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp Writer.Write(code); } } + + private bool ShouldGenerateInstrumentationForExpressions() + { + // Only generate instrumentation for expression blocks if instrumentation is enabled and we're generating a + // "Write(").Builder.Build();
+ var builder = new CodeTreeBuilder();
+
+ // Act
+ builder.AddLiteralChunk("", previousSpan);
+ builder.AddLiteralChunk(" ", newSpan);
+
+ // Assert
+ var chunk = Assert.Single(builder.CodeTree.Chunks);
+ var literalChunk = Assert.IsType ", literalChunk.Text);
+ var span = Assert.IsType(literalChunk.Association);
+ Assert.Equal(previousSpan.Symbols.Concat(newSpan.Symbols), span.Symbols);
+ }
+
+ [Fact]
+ public void AddLiteralChunk_AddsChunkToCodeTree_IfPreviousChunkWasNotLiteral()
+ {
+ // Arrange
+ var spanFactory = SpanFactory.CreateCsHtml();
+ var codeSpan = spanFactory.Code("int a = 10;")
+ .AsStatement()
+ .Builder.Build();
+ var literalSpan = spanFactory.Markup(" ").Builder.Build();
+ var builder = new CodeTreeBuilder();
+
+ // Act
+ builder.AddStatementChunk("int a = 10;", codeSpan);
+ builder.AddLiteralChunk(" ", literalSpan);
+
+ // Assert
+ var chunks = builder.CodeTree.Chunks;
+ Assert.Equal(2, chunks.Count);
+ var statementChunk = Assert.IsType ", literalChunk.Text);
+ Assert.Same(literalSpan, literalChunk.Association);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs
index a798413e58..9fc495ed10 100644
--- a/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs
+++ b/test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs
@@ -118,8 +118,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
"WriteLiteralTo",
"Template",
"DefineSection",
- "BeginContext",
- "EndContext")
+ "Instrumentation.BeginContext",
+ "Instrumentation.EndContext")
{
LayoutPropertyName = "Layout",
ResolveUrlMethodName = "Href"
@@ -130,6 +130,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
}
host.IsIndentingWithTabs = withTabs;
+ host.EnableInstrumentation = true;
RazorTemplateEngine engine = new RazorTemplateEngine(host);
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/Await.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/Await.cs
index 0de02b096c..daeee101d8 100644
--- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/Await.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/Await.cs
@@ -22,8 +22,11 @@ namespace TestOutput
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
+ Instrumentation.BeginContext(91, 100, true);
WriteLiteral("\r\n Basic Asynch" +
"ronous Expression: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(192, 11, false);
Write(
#line 10 "Await.cshtml"
await Foo()
@@ -32,7 +35,11 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(203, 42, true);
WriteLiteral(" Basic Asynchronous Template: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(247, 11, false);
Write(
#line 11 "Await.cshtml"
await Foo()
@@ -41,14 +48,20 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(259, 43, true);
WriteLiteral(" Basic Asynchronous Statement: ");
+ Instrumentation.EndContext();
#line 12 "Await.cshtml"
await Foo();
#line default
#line hidden
+ Instrumentation.BeginContext(319, 54, true);
WriteLiteral(" Basic Asynchronous Statement Nested: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(376, 11, false);
Write(
#line 13 "Await.cshtml"
await Foo()
@@ -57,14 +70,20 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(387, 5, true);
WriteLiteral(" ");
+ Instrumentation.EndContext();
#line 13 "Await.cshtml"
#line default
#line hidden
+ Instrumentation.BeginContext(393, 54, true);
WriteLiteral(" Basic Incomplete Asynchronous Statement: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(448, 5, false);
Write(
#line 14 "Await.cshtml"
await
@@ -73,8 +92,12 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(453, 124, true);
WriteLiteral(" Advanced Asynchronous Expression: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(578, 15, false);
Write(
#line 19 "Await.cshtml"
await Foo(1, 2)
@@ -83,7 +106,11 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(593, 56, true);
WriteLiteral(" Advanced Asynchronous Expression Extended: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(650, 19, false);
Write(
#line 20 "Await.cshtml"
await Foo.Bar(1, 2)
@@ -92,7 +119,11 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(669, 45, true);
WriteLiteral(" Advanced Asynchronous Template: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(716, 22, false);
Write(
#line 21 "Await.cshtml"
await Foo("bob", true)
@@ -101,21 +132,29 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(739, 46, true);
WriteLiteral(" Advanced Asynchronous Statement: ");
+ Instrumentation.EndContext();
#line 22 "Await.cshtml"
await Foo(something, hello: "world");
#line default
#line hidden
+ Instrumentation.BeginContext(827, 55, true);
WriteLiteral(" Advanced Asynchronous Statement Extended: ");
+ Instrumentation.EndContext();
#line 23 "Await.cshtml"
await Foo.Bar(1, 2)
#line default
#line hidden
+ Instrumentation.BeginContext(906, 57, true);
WriteLiteral(" Advanced Asynchronous Statement Nested: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(966, 27, false);
Write(
#line 24 "Await.cshtml"
await Foo(boolValue: false)
@@ -124,14 +163,20 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(993, 5, true);
WriteLiteral(" ");
+ Instrumentation.EndContext();
#line 24 "Await.cshtml"
#line default
#line hidden
+ Instrumentation.BeginContext(999, 57, true);
WriteLiteral(" Advanced Incomplete Asynchronous Statement: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(1057, 19, false);
Write(
#line 25 "Await.cshtml"
await ("wrrronggg")
@@ -140,7 +185,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(1076, 16, true);
WriteLiteral(" Hello from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(69, 1, false);
Write(
#line 6 "Blocks.cshtml"
i
@@ -36,7 +41,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(71, 6, true);
WriteLiteral(" We wrote 10 lines! No really, we wrote 10 lines! Actually, we didn\'t... Hello again from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(378, 1, false);
Write(
#line 24 "Blocks.cshtml"
j
@@ -98,28 +121,38 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(380, 6, true);
WriteLiteral(" That time, we wrote 5 lines! Oh no! An error occurred: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(500, 10, false);
Write(
#line 30 "Blocks.cshtml"
ex.Message
@@ -128,14 +161,20 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(511, 6, true);
WriteLiteral(" i is now ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(535, 1, false);
Write(
#line 33 "Blocks.cshtml"
i
@@ -144,14 +183,19 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(536, 8, true);
WriteLiteral(" This block is locked, for your security! (
#line 5 "ConditionalAttributes.cshtml"
@@ -30,7 +32,9 @@ namespace TestOutput
#line default
#line hidden
, 82), false));
+ Instrumentation.BeginContext(87, 11, true);
WriteLiteral(" />\r\n (
#line 6 "ConditionalAttributes.cshtml"
@@ -39,7 +43,9 @@ namespace TestOutput
#line default
#line hidden
, 110), false));
+ Instrumentation.BeginContext(115, 11, true);
WriteLiteral(" />\r\n (
#line 7 "ConditionalAttributes.cshtml"
@@ -48,7 +54,9 @@ namespace TestOutput
#line default
#line hidden
, 134), false), Tuple.Create(Tuple.Create(" ", 138), Tuple.Create("foo", 139), true));
+ Instrumentation.BeginContext(143, 31, true);
WriteLiteral(" />\r\n (
#line 8 "ConditionalAttributes.cshtml"
@@ -57,7 +65,9 @@ namespace TestOutput
#line default
#line hidden
, 184), false));
+ Instrumentation.BeginContext(188, 31, true);
WriteLiteral(" />\r\n (
#line 9 "ConditionalAttributes.cshtml"
@@ -66,7 +76,9 @@ namespace TestOutput
#line default
#line hidden
, 233), false));
+ Instrumentation.BeginContext(237, 11, true);
WriteLiteral(" />\r\n (new Template((__razor_attribute_value_writer) => {
#line 10 "ConditionalAttributes.cshtml"
@@ -75,6 +87,7 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(276, 3, false);
WriteTo(__razor_attribute_value_writer,
#line 10 "ConditionalAttributes.cshtml"
cls
@@ -83,6 +96,7 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
#line 10 "ConditionalAttributes.cshtml"
}
@@ -91,9 +105,13 @@ namespace TestOutput
}
), 256), false));
+ Instrumentation.BeginContext(282, 11, true);
WriteLiteral(" />\r\n (Href("~/Foo"), 300), false));
+ Instrumentation.BeginContext(306, 16, true);
WriteLiteral(" />\r\n \r\n \r\n \r\n");
+ Instrumentation.EndContext();
#line 15 "ConditionalAttributes.cshtml"
#line default
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExplicitExpression.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExplicitExpression.cs
index e9e2aef118..ac738c680a 100644
--- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExplicitExpression.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExplicitExpression.cs
@@ -13,7 +13,10 @@ namespace TestOutput
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
+ Instrumentation.BeginContext(0, 8, true);
WriteLiteral("1 + 1 = ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(10, 3, false);
Write(
#line 1 "ExplicitExpression.cshtml"
1+1
@@ -22,6 +25,7 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
}
#pragma warning restore 1998
}
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExpressionsInCode.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExpressionsInCode.cs
index ff44ada871..5af9382bd2 100644
--- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExpressionsInCode.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ExpressionsInCode.cs
@@ -21,7 +21,9 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(54, 4, true);
WriteLiteral("\r\n\r\n");
+ Instrumentation.EndContext();
#line 6 "ExpressionsInCode.cshtml"
if(foo != null) {
@@ -29,6 +31,7 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(83, 3, false);
Write(
#line 7 "ExpressionsInCode.cshtml"
foo
@@ -37,6 +40,7 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
#line 7 "ExpressionsInCode.cshtml"
} else {
@@ -44,14 +48,18 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(98, 25, true);
WriteLiteral(" Foo is Null! \r\n");
+ Instrumentation.EndContext();
#line 13 "ExpressionsInCode.cshtml"
if(!String.IsNullOrEmpty(bar)) {
@@ -59,6 +67,7 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(174, 21, false);
Write(
#line 14 "ExpressionsInCode.cshtml"
bar.Replace("F", "B")
@@ -67,6 +76,7 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
#line 14 "ExpressionsInCode.cshtml"
}
@@ -74,7 +84,9 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(201, 4, true);
WriteLiteral(" This is item #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(55, 1, false);
Write(
#line 2 "ImplicitExpression.cshtml"
i
@@ -28,7 +31,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(56, 6, true);
WriteLiteral(" Path\'s full type name is ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(99, 21, false);
Write(
#line 5 "Imports.cshtml"
typeof(Path).FullName
@@ -39,7 +42,11 @@ using System
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(120, 40, true);
WriteLiteral(" Foo\'s actual full type name is ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(161, 20, false);
Write(
#line 6 "Imports.cshtml"
typeof(Foo).FullName
@@ -48,7 +55,10 @@ using System
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(181, 4, true);
WriteLiteral(" Bar Hello, World Hello from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(200, 1, false);
+ Write(
+#line 13 "Instrumented.cshtml"
+ i
+
+#line default
+#line hidden
+ );
+
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(202, 6, true);
+ WriteLiteral(" We wrote 10 lines! No really, we wrote 10 lines! Actually, we didn\'t... Hello again from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(509, 1, false);
+ Write(
+#line 31 "Instrumented.cshtml"
+ j
+
+#line default
+#line hidden
+ );
+
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(511, 6, true);
+ WriteLiteral(" That time, we wrote 5 lines! Oh no! An error occurred: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(631, 10, false);
+ Write(
+#line 37 "Instrumented.cshtml"
+ ex.Message
+
+#line default
+#line hidden
+ );
+
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(642, 6, true);
+ WriteLiteral(" This block is locked, for your security! Hello from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(69, 12, false);
Write(
#line 3 "MarkupInCodeBlock.cshtml"
i.ToString()
@@ -29,14 +32,19 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(82, 6, true);
WriteLiteral(" Hello from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(69, 1, false);
Write(
#line 6 ""
i
@@ -36,7 +41,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(71, 6, true);
WriteLiteral(" We wrote 10 lines! No really, we wrote 10 lines! Actually, we didn\'t... Hello again from C#, #");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(378, 1, false);
Write(
#line 24 ""
j
@@ -98,28 +121,38 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(380, 6, true);
WriteLiteral(" That time, we wrote 5 lines! Oh no! An error occurred: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(500, 10, false);
Write(
#line 30 ""
ex.Message
@@ -128,7 +161,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(511, 6, true);
WriteLiteral(" i is now ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(571, 1, false);
Write(
#line 34 ""
i
@@ -151,14 +190,19 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(572, 8, true);
WriteLiteral(" This block is locked, for your security! This should be shown But this should show the comment syntax: ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(310, 3, false);
Write(
#line 13 "RazorComments.cshtml"
bar
@@ -53,7 +60,11 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(313, 8, true);
WriteLiteral(" \r\n");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(430, 16, false);
Write(
#line 21 "Templates.cshtml"
Repeat(10,
@@ -103,7 +126,10 @@ namespace TestOutput
#line default
#line hidden
item => new Template((__razor_template_writer) => {
+ Instrumentation.BeginContext(448, 14, true);
WriteLiteralTo(__razor_template_writer, " This is line#");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(463, 4, false);
WriteTo(__razor_template_writer,
#line 22 "Templates.cshtml"
item
@@ -112,7 +138,10 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(467, 17, true);
WriteLiteralTo(__razor_template_writer, " of markup Bar Hello, World Hello from C#, #@(i) We wrote 10 lines! No really, we wrote 10 lines! Actually, we didn't... Hello again from C#, #@(j) That time, we wrote 5 lines! Oh no! An error occurred: @(ex.Message) This block is locked, for your security!Basic Asynchronous Expression Test
\r\n Advanced Asynchronous Expression Test
" +
"\r\n (Href("~/images/submit.png"), 22), false));
+ Instrumentation.BeginContext(42, 3, true);
WriteLiteral(" />");
+ Instrumentation.EndContext();
}
#pragma warning restore 1998
}
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/HtmlCommentWithQuote_Single.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/HtmlCommentWithQuote_Single.cs
index a7614d64cb..37eae1bf47 100644
--- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/HtmlCommentWithQuote_Single.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/HtmlCommentWithQuote_Single.cs
@@ -13,9 +13,13 @@ namespace TestOutput
#pragma warning disable 1998
public override async Task ExecuteAsync()
{
+ Instrumentation.BeginContext(0, 16, true);
WriteLiteral("\r\n
(Href("~/images/submit.png"), 22), false));
+ Instrumentation.BeginContext(42, 3, true);
WriteLiteral(" />");
+ Instrumentation.EndContext();
}
#pragma warning restore 1998
}
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ImplicitExpression.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ImplicitExpression.cs
index aabe11373a..4114598df0 100644
--- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ImplicitExpression.cs
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ImplicitExpression.cs
@@ -19,7 +19,10 @@ namespace TestOutput
#line default
#line hidden
+ Instrumentation.BeginContext(33, 21, true);
WriteLiteral("
\r\n");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(379, 11, false);
Write(
#line 17 "Templates.cshtml"
Repeat(10,
@@ -75,7 +88,10 @@ namespace TestOutput
#line default
#line hidden
item => new Template((__razor_template_writer) => {
+ Instrumentation.BeginContext(391, 10, true);
WriteLiteralTo(__razor_template_writer, "
\r\n\r\n
\r\n");
+ Instrumentation.EndContext();
}
)
#line 23 "Templates.cshtml"
@@ -122,7 +151,11 @@ namespace TestOutput
#line hidden
);
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(485, 20, true);
WriteLiteral("\r\n\r\n ");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(506, 11, false);
Write(
#line 27 "Templates.cshtml"
Repeat(10,
@@ -130,7 +163,10 @@ namespace TestOutput
#line default
#line hidden
item => new Template((__razor_template_writer) => {
+ Instrumentation.BeginContext(518, 20, true);
WriteLiteralTo(__razor_template_writer, "
");
+ Instrumentation.EndContext();
}
#pragma warning restore 1998
}
diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/Instrumented.cshtml b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/Instrumented.cshtml
new file mode 100644
index 0000000000..4d9b03eb84
--- /dev/null
+++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/Instrumented.cshtml
@@ -0,0 +1,42 @@
+@helper Strong(string s) {
+ @s
+}
+
+@{
+ int i = 1;
+ var foo = @\r\n
\r\n