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 cb0c5d6b05..de0b0c9d6d 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 @@ -102,8 +102,9 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp protected override void Visit(LiteralChunk chunk) { - if (!Context.Host.DesignTimeMode && String.IsNullOrEmpty(chunk.Text)) + if (Context.Host.DesignTimeMode || string.IsNullOrEmpty(chunk.Text)) { + // Skip generating the chunk if we're in design time or if the chunk is empty. return; } @@ -112,22 +113,19 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp Writer.WriteStartInstrumentationContext(Context, chunk.Association, isLiteral: true); } - if (!String.IsNullOrEmpty(chunk.Text) && !Context.Host.DesignTimeMode) + if (!string.IsNullOrEmpty(Context.TargetWriterName)) { - if (!String.IsNullOrEmpty(Context.TargetWriterName)) - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralToMethodName) - .Write(Context.TargetWriterName) - .WriteParameterSeparator(); - } - else - { - Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralMethodName); - } - - Writer.WriteStringLiteral(chunk.Text) - .WriteEndMethodInvocation(); + Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralToMethodName) + .Write(Context.TargetWriterName) + .WriteParameterSeparator(); } + else + { + Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralMethodName); + } + + Writer.WriteStringLiteral(chunk.Text) + .WriteEndMethodInvocation(); if (Context.Host.EnableInstrumentation) { @@ -162,10 +160,11 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { if (Context.Host.DesignTimeMode) { - return; // Don't generate anything! + // Render the children as is without wrapping them in calls to WriteAttribute + Accept(chunk.Children); + return; } - Chunk code = chunk.Children.FirstOrDefault(); ExpressionRenderingMode currentRenderingMode = Context.ExpressionRenderingMode; string currentTargetWriterName = Context.TargetWriterName; @@ -174,6 +173,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp Writer.WriteParameterSeparator() .WriteLine(); + var code = chunk.Children.FirstOrDefault(); if (code is ExpressionChunk || code is ExpressionBlockChunk) { Writer.WriteStartMethodInvocation("Tuple.Create") @@ -220,9 +220,17 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp protected override void Visit(LiteralCodeAttributeChunk chunk) { + var visitChildren = chunk.Value == null; + if (Context.Host.DesignTimeMode) { - return; // Don't generate anything! + // Render the attribute without wrapping it in a call to WriteAttribute + if (visitChildren) + { + Accept(chunk.Children); + } + + return; } Writer.WriteParameterSeparator() @@ -230,7 +238,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp .WriteLocationTaggedString(chunk.Prefix) .WriteParameterSeparator(); - if (chunk.Children.Count > 0 || chunk.Value == null) + if (visitChildren) { Writer.WriteStartMethodInvocation("Tuple.Create", new string[] { "System.Object", "System.Int32" }); @@ -247,7 +255,6 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp .WriteParameterSeparator() .WriteBooleanLiteral(false) .WriteEndMethodInvocation(false); - } else { @@ -262,7 +269,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { if (Context.Host.DesignTimeMode) { - return; // Don't generate anything! + // Render the attribute without wrapping it in a "WriteAttribute" invocation + Accept(chunk.Children); + + return; } if (!String.IsNullOrEmpty(Context.TargetWriterName)) diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs index 61a038dc88..c80cd9ea71 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs @@ -409,6 +409,42 @@ namespace Microsoft.AspNet.Razor.Test.Generator tabTest: TabTest.NoTabs); } + [Fact] + public void CSharpCodeGenerator_CorrectlyGeneratesAttributes_AtDesignTime() + { + var expectedDesignTimePragmas = new[] + { + BuildLineMapping(2, 0, 549, 22, 2, 48), + BuildLineMapping(66, 3, 692, 31, 20, 6), + BuildLineMapping(83, 4, 788, 38, 15, 3), + BuildLineMapping(90, 4, 887, 43, 22, 6), + BuildLineMapping(111, 5, 987, 50, 19, 3), + BuildLineMapping(118, 5, 1090, 55, 26, 6), + BuildLineMapping(135, 6, 1186, 62, 15, 3), + BuildLineMapping(146, 6, 1289, 67, 26, 6), + BuildLineMapping(185, 7, 1407, 74, 37, 2), + BuildLineMapping(191, 7, 1526, 79, 43, 6), + BuildLineMapping(234, 8, 1648, 86, 41, 2), + BuildLineMapping(240, 8, 1771, 91, 47, 6), + BuildLineMapping(257, 9, 15, 1867, 98, 14, 18), + BuildLineMapping(276, 9, 1995, 104, 34, 3), + BuildLineMapping(279, 9, 2110, 109, 37, 2), + BuildLineMapping(285, 9, 2231, 115, 43, 6), + BuildLineMapping(309, 10, 2335, 122, 22, 6), + BuildLineMapping(329, 11, 2435, 129, 18, 44), + BuildLineMapping(407, 11, 2650, 134, 96, 6), + BuildLineMapping(427, 12, 2750, 141, 18, 60), + BuildLineMapping(521, 12, 2997, 146, 112, 6), + BuildLineMapping(638, 13, 3194, 153, 115, 2) + }; + + RunTest("ConditionalAttributes", + baselineName: "ConditionalAttributes.DesignTime", + designTimeMode: true, + tabTest: TabTest.NoTabs, + expectedDesignTimePragmas: expectedDesignTimePragmas); + } + private void OpenedIf(bool withTabs) { int tabOffsetForMapping = 7; diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ConditionalAttributes.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ConditionalAttributes.DesignTime.cs new file mode 100644 index 0000000000..15ba430321 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ConditionalAttributes.DesignTime.cs @@ -0,0 +1,162 @@ +namespace TestOutput +{ + using System; + using System.Threading.Tasks; + + public class ConditionalAttributes + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + #pragma warning restore 219 + } + #line hidden + public ConditionalAttributes() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { +#line 1 "ConditionalAttributes.cshtml" + + var ch = true; + var cls = "bar"; + + +#line default +#line hidden + +#line 4 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 5 "ConditionalAttributes.cshtml" + __o = cls; + +#line default +#line hidden +#line 5 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 6 "ConditionalAttributes.cshtml" + __o = cls; + +#line default +#line hidden +#line 6 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 7 "ConditionalAttributes.cshtml" + __o = cls; + +#line default +#line hidden +#line 7 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 8 "ConditionalAttributes.cshtml" + __o = ch; + +#line default +#line hidden +#line 8 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 9 "ConditionalAttributes.cshtml" + __o = ch; + +#line default +#line hidden +#line 9 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 10 "ConditionalAttributes.cshtml" + if(cls != null) { + +#line default +#line hidden + +#line 10 "ConditionalAttributes.cshtml" + __o = cls; + +#line default +#line hidden +#line 10 "ConditionalAttributes.cshtml" + } + +#line default +#line hidden + +#line 10 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 11 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 12 "ConditionalAttributes.cshtml" + __o = Url.Content("~/Scripts/jquery-1.6.2.min.js"); + +#line default +#line hidden +#line 12 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 13 "ConditionalAttributes.cshtml" + __o = Url.Content("~/Scripts/modernizr-2.0.6-development-only.js"); + +#line default +#line hidden +#line 13 "ConditionalAttributes.cshtml" + + + +#line default +#line hidden + +#line 14 "ConditionalAttributes.cshtml" + + +#line default +#line hidden + + } + #pragma warning restore 1998 + } +}