From 54155e47e5ffb7122c6576b5d424fad5b9a9f4b1 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Wed, 22 Oct 2014 15:59:35 -0700 Subject: [PATCH] Add DesignTime code generation support for TagHelpers. - We now generate a subset of the TagHelper runtime code during DesignTime. This enables users to see errors in the editor - Added tests to validate design time code generation. - Refactored runtime code generation tests (we now use a lot of their infrastructure for the design time pieces). #208 --- .../CSharp/CSharpTagHelperCodeRenderer.cs | 90 +++++-- .../CSharpTagHelperFieldDeclarationVisitor.cs | 29 ++- .../Generator/CSharpTagHelperRenderingTest.cs | 219 +++++++++++++----- .../CS/Output/BasicTagHelpers.DesignTime.cs | 49 ++++ .../CS/Output/ComplexTagHelpers.DesignTime.cs | 133 +++++++++++ .../ContentBehaviorTagHelpers.DesignTime.cs | 45 ++++ .../CS/Output/SingleTagHelper.DesignTime.cs | 38 +++ .../CS/Output/SingleTagHelper.cs | 6 +- .../CS/Source/SingleTagHelper.cshtml | 2 +- 9 files changed, 521 insertions(+), 90 deletions(-) create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/BasicTagHelpers.DesignTime.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ContentBehaviorTagHelpers.DesignTime.cs create mode 100644 test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.DesignTime.cs diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpTagHelperCodeRenderer.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpTagHelperCodeRenderer.cs index 83af0e72e7..3eff0ea711 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpTagHelperCodeRenderer.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/CSharpTagHelperCodeRenderer.cs @@ -26,6 +26,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp private readonly CodeBuilderContext _context; private readonly IChunkVisitor _bodyVisitor; private readonly GeneratedTagHelperContext _tagHelperContext; + private readonly bool _designTimeMode; /// /// Instantiates a new . @@ -42,6 +43,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp _writer = writer; _context = context; _tagHelperContext = context.Host.GeneratedClassContext.GeneratedTagHelperContext; + _designTimeMode = context.Host.DesignTimeMode; AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer(); } @@ -53,12 +55,6 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp /// A to render. public void RenderTagHelper(TagHelperChunk chunk) { - // TODO: Implement design time support for tag helpers in https://github.com/aspnet/Razor/issues/83 - if (_context.Host.DesignTimeMode) - { - return; - } - var tagHelperDescriptors = chunk.Descriptors; // Find the first content behavior that doesn't have a content behavior of None. @@ -128,6 +124,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp private void RenderBeginTagHelperScope(string tagName) { + // Scopes/execution contexts are a runtime feature. + if (_designTimeMode) + { + return; + } + // Call into the tag helper scope manager to start a new tag helper scope. // Also capture the value as the current execution context. _writer.WriteStartAssignment(ExecutionContextVariableName) @@ -157,9 +159,13 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp tagHelperDescriptor.TagHelperName) .WriteEndMethodInvocation(); - _writer.WriteInstanceMethodInvocation(ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddMethodName, - tagHelperVariableName); + // Execution contexts are a runtime feature. + if (!_designTimeMode) + { + _writer.WriteInstanceMethodInvocation(ExecutionContextVariableName, + _tagHelperContext.ExecutionContextAddMethodName, + tagHelperVariableName); + } // Render all of the bound attribute values for the tag helper. RenderBoundHTMLAttributes(chunk.Attributes, @@ -250,6 +256,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp // End the assignment to the attribute. _writer.WriteLine(";"); + // Execution contexts are a runtime feature. + if (_designTimeMode) + { + continue; + } + // We need to inform the context of the attribute value. _writer.WriteStartInstanceMethodInvocation( ExecutionContextVariableName, @@ -286,8 +298,15 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp BuildBufferedWritingScope(attributeValue); } - _writer.WriteStartInstanceMethodInvocation(ExecutionContextVariableName, - _tagHelperContext.ExecutionContextAddHtmlAttributeMethodName); + // Execution contexts are a runtime feature, therefore no need to add anything to them. + if (_designTimeMode) + { + continue; + } + + _writer.WriteStartInstanceMethodInvocation( + ExecutionContextVariableName, + _tagHelperContext.ExecutionContextAddHtmlAttributeMethodName); _writer.WriteStringLiteral(htmlAttribute.Key) .WriteParameterSeparator(); @@ -322,6 +341,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp private void RenderEndTagHelpersScope() { + // Scopes/execution contexts are a runtime feature. + if (_designTimeMode) + { + return; + } + _writer.WriteStartAssignment(ExecutionContextVariableName) .WriteInstanceMethodInvocation(ScopeManagerVariableName, _tagHelperContext.ScopeManagerEndMethodName); @@ -329,6 +354,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp private void RenderTagOutput(string tagOutputMethodName) { + // Rendering output is a runtime feature. + if (_designTimeMode) + { + return; + } + CSharpCodeVisitor.RenderPreWriteStart(_writer, _context); _writer.Write(ExecutionContextVariableName) @@ -341,6 +372,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp private void RenderRunTagHelpers(bool bufferedBody) { + // No need to run anything in design time mode. + if (_designTimeMode) + { + return; + } + _writer.Write(ExecutionContextVariableName) .Write(".") .Write(_tagHelperContext.ExecutionContextOutputPropertyName) @@ -411,12 +448,20 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { _context.Host.EnableInstrumentation = false; - _writer.WriteMethodInvocation(_tagHelperContext.StartWritingScopeMethodName); + // Scopes are a runtime feature. + if (!_designTimeMode) + { + _writer.WriteMethodInvocation(_tagHelperContext.StartWritingScopeMethodName); + } _bodyVisitor.Accept(chunks); - _writer.WriteStartAssignment(StringValueBufferVariableName) - .WriteMethodInvocation(_tagHelperContext.EndWritingScopeMethodName); + // Scopes are a runtime feature. + if (!_designTimeMode) + { + _writer.WriteStartAssignment(StringValueBufferVariableName) + .WriteMethodInvocation(_tagHelperContext.EndWritingScopeMethodName); + } } finally { @@ -434,11 +479,20 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp AttributeValueCodeRenderer.RenderAttributeValue(attributeDescriptor, _writer, _context, valueRenderer); } - private static void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer) + private void RenderBufferedAttributeValueAccessor(CSharpCodeWriter writer) { - writer.WriteInstanceMethodInvocation(StringValueBufferVariableName, - "ToString", - endLine: false); + if (_designTimeMode) + { + // There is no value buffer in design time mode but we still want to write out a value. We write a + // value to ensure the tag helper's property type is string. + writer.Write("string.Empty"); + } + else + { + writer.WriteInstanceMethodInvocation(StringValueBufferVariableName, + "ToString", + endLine: false); + } } private static bool IsStringAttribute(TagHelperAttributeDescriptor attributeDescriptor) diff --git a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs index be9705f518..83c1df67fd 100644 --- a/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Generator/Compiler/CodeBuilder/CSharp/Visitors/CSharpTagHelperFieldDeclarationVisitor.cs @@ -28,23 +28,28 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp { _foundTagHelpers = true; + // We want to hide declared TagHelper fields so they cannot be stepped over via a debugger. Writer.WriteLineHiddenDirective(); - WritePrivateField(typeof(TextWriter).FullName, - CSharpTagHelperCodeRenderer.StringValueBufferVariableName, - value: null); + // Runtime fields aren't useful during design time. + if (!Context.Host.DesignTimeMode) + { + WritePrivateField(typeof(TextWriter).FullName, + CSharpTagHelperCodeRenderer.StringValueBufferVariableName, + value: null); - WritePrivateField(_tagHelperContext.ExecutionContextTypeName, - CSharpTagHelperCodeRenderer.ExecutionContextVariableName, - value: null); + WritePrivateField(_tagHelperContext.ExecutionContextTypeName, + CSharpTagHelperCodeRenderer.ExecutionContextVariableName, + value: null); - WritePrivateField(_tagHelperContext.RunnerTypeName, - CSharpTagHelperCodeRenderer.RunnerVariableName, - "new " + _tagHelperContext.RunnerTypeName + "()"); + WritePrivateField(_tagHelperContext.RunnerTypeName, + CSharpTagHelperCodeRenderer.RunnerVariableName, + "new " + _tagHelperContext.RunnerTypeName + "()"); - WritePrivateField(_tagHelperContext.ScopeManagerTypeName, - CSharpTagHelperCodeRenderer.ScopeManagerVariableName, - "new " + _tagHelperContext.ScopeManagerTypeName + "()"); + WritePrivateField(_tagHelperContext.ScopeManagerTypeName, + CSharpTagHelperCodeRenderer.ScopeManagerVariableName, + "new " + _tagHelperContext.ScopeManagerTypeName + "()"); + } } foreach (var descriptor in chunk.Descriptors) diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs index f2acd0b425..68427874c6 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs @@ -11,6 +11,168 @@ namespace Microsoft.AspNet.Razor.Test.Generator { public class CSharpTagHelperRenderingTest : TagHelperTestBase { + private static IEnumerable PAndInputTagHelperDescriptors + { + get + { + var pAgePropertyInfo = typeof(TestType).GetProperty("Age"); + var inputTypePropertyInfo = typeof(TestType).GetProperty("Type"); + var checkedPropertyInfo = typeof(TestType).GetProperty("Checked"); + return new[] + { + new TagHelperDescriptor("p", + "PTagHelper", + ContentBehavior.None, + new [] { + new TagHelperAttributeDescriptor("age", pAgePropertyInfo) + }), + new TagHelperDescriptor("input", + "InputTagHelper", + ContentBehavior.None, + new TagHelperAttributeDescriptor[] { + new TagHelperAttributeDescriptor("type", inputTypePropertyInfo) + }), + new TagHelperDescriptor("input", + "InputTagHelper2", + ContentBehavior.None, + new TagHelperAttributeDescriptor[] { + new TagHelperAttributeDescriptor("type", inputTypePropertyInfo), + new TagHelperAttributeDescriptor("checked", checkedPropertyInfo) + }) + }; + } + } + + private static IEnumerable ContentBehaviorTagHelperDescriptors + { + get + { + return new[] + { + new TagHelperDescriptor("modify", "ModifyTagHelper", ContentBehavior.Modify), + new TagHelperDescriptor("none", "NoneTagHelper", ContentBehavior.None), + new TagHelperDescriptor("append", "AppendTagHelper", ContentBehavior.Append), + new TagHelperDescriptor("prepend", "PrependTagHelper", ContentBehavior.Prepend), + new TagHelperDescriptor("replace", "ReplaceTagHelper", ContentBehavior.Replace) + }; + } + } + + public static TheoryData DesignTimeTagHelperTestData + { + get + { + // Test resource name, baseline resource name, expected TagHelperDescriptors, expected LineMappings + return new TheoryData, List> + { + { + "SingleTagHelper", + "SingleTagHelper.DesignTime", + PAndInputTagHelperDescriptors, + new List + { + BuildLineMapping(documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 475, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 11) + } + }, + { + "BasicTagHelpers", + "BasicTagHelpers.DesignTime", + PAndInputTagHelperDescriptors, + new List + { + BuildLineMapping(documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 475, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 11) + } + }, + { + "ContentBehaviorTagHelpers", + "ContentBehaviorTagHelpers.DesignTime", + ContentBehaviorTagHelperDescriptors, + new List + { + BuildLineMapping(documentAbsoluteIndex: 14, + documentLineIndex: 0, + generatedAbsoluteIndex: 495, + generatedLineIndex: 15, + characterOffsetIndex: 14, + contentLength: 11) + } + }, + { + "ComplexTagHelpers", + "ComplexTagHelpers.DesignTime", + PAndInputTagHelperDescriptors, + new List + { + BuildLineMapping(14, 0, 479, 15, 14, 11), + BuildLineMapping(30, 2, 1, 995, 35, 0, 48), + BuildLineMapping(157, 7, 32, 1177, 45, 6, 12), + BuildLineMapping(205, 9, 1260, 50, 0, 12), + BuildLineMapping(218, 9, 13, 1356, 56, 12, 27), + BuildLineMapping(346, 12, 1754, 68, 0, 48), + BuildLineMapping(440, 15, 46, 2004, 78, 6, 8), + 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) + } + } + }; + } + } + + [Theory] + [MemberData(nameof(DesignTimeTagHelperTestData))] + public void TagHelpers_GenerateExpectedDesignTimeOutput(string testName, + string baseLineName, + IEnumerable tagHelperDescriptors, + List expectedDesignTimePragmas) + { + // Act & Assert + RunTagHelperTest(testName, + baseLineName, + designTimeMode: true, + tagHelperDescriptors: tagHelperDescriptors, + expectedDesignTimePragmas: expectedDesignTimePragmas); + } + + public static TheoryData RuntimeTimeTagHelperTestData + { + get + { + // Test resource name, expected TagHelperDescriptors + // Note: The baseline resource name is equivalent to the test resource name. + return new TheoryData> + { + { "SingleTagHelper", PAndInputTagHelperDescriptors }, + { "BasicTagHelpers", PAndInputTagHelperDescriptors }, + { "BasicTagHelpers.RemoveTagHelper", PAndInputTagHelperDescriptors }, + { "ContentBehaviorTagHelpers", ContentBehaviorTagHelperDescriptors }, + { "ComplexTagHelpers", PAndInputTagHelperDescriptors }, + }; + } + } + + [Theory] + [MemberData(nameof(RuntimeTimeTagHelperTestData))] + public void TagHelpers_GenerateExpectedRuntimeOutput(string testName, + IEnumerable tagHelperDescriptors) + { + // Act & Assert + RunTagHelperTest(testName, tagHelperDescriptors: tagHelperDescriptors); + } + [Fact] public void CSharpCodeGenerator_CorrectlyGeneratesMappings_ForRemoveTagHelperDirective() { @@ -79,64 +241,9 @@ namespace Microsoft.AspNet.Razor.Test.Generator RunTagHelperTest(testType, tagHelperDescriptors: tagHelperDescriptors); } - [Theory] - [InlineData("SingleTagHelper")] - [InlineData("BasicTagHelpers")] - [InlineData("BasicTagHelpers.RemoveTagHelper")] - [InlineData("ComplexTagHelpers")] - public void TagHelpers_GenerateExpectedOutput(string testType) - { - // Arrange - var pFooPropertyInfo = typeof(TestType).GetProperty("Foo"); - var inputTypePropertyInfo = typeof(TestType).GetProperty("Type"); - var checkedPropertyInfo = typeof(TestType).GetProperty("Checked"); - var tagHelperDescriptors = new TagHelperDescriptor[] - { - new TagHelperDescriptor("p", - "PTagHelper", - ContentBehavior.None, - new [] { - new TagHelperAttributeDescriptor("foo", pFooPropertyInfo) - }), - new TagHelperDescriptor("input", - "InputTagHelper", - ContentBehavior.None, - new TagHelperAttributeDescriptor[] { - new TagHelperAttributeDescriptor("type", inputTypePropertyInfo) - }), - new TagHelperDescriptor("input", - "InputTagHelper2", - ContentBehavior.None, - new TagHelperAttributeDescriptor[] { - new TagHelperAttributeDescriptor("type", inputTypePropertyInfo), - new TagHelperAttributeDescriptor("checked", checkedPropertyInfo) - }) - }; - - // Act & Assert - RunTagHelperTest(testType, tagHelperDescriptors: tagHelperDescriptors); - } - - [Fact] - public void TagHelpers_WithContentBehaviors_GenerateExpectedOutput() - { - // Arrange - var tagHelperDescriptors = new TagHelperDescriptor[] - { - new TagHelperDescriptor("modify", "ModifyTagHelper", ContentBehavior.Modify), - new TagHelperDescriptor("none", "NoneTagHelper", ContentBehavior.None), - new TagHelperDescriptor("append", "AppendTagHelper", ContentBehavior.Append), - new TagHelperDescriptor("prepend", "PrependTagHelper", ContentBehavior.Prepend), - new TagHelperDescriptor("replace", "ReplaceTagHelper", ContentBehavior.Replace), - }; - - // Act & Assert - RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptors: tagHelperDescriptors); - } - private class TestType { - public int Foo { get; set; } + public int Age { get; set; } public string Type { get; set; } diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/BasicTagHelpers.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/BasicTagHelpers.DesignTime.cs new file mode 100644 index 0000000000..2e64d06da7 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/BasicTagHelpers.DesignTime.cs @@ -0,0 +1,49 @@ +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class BasicTagHelpers + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + string __tagHelperDirectiveSyntaxHelper = null; + __tagHelperDirectiveSyntaxHelper = +#line 1 "BasicTagHelpers.cshtml" + "something" + +#line default +#line hidden + ; + #pragma warning restore 219 + } + #line hidden + private PTagHelper __PTagHelper = null; + private InputTagHelper __InputTagHelper = null; + private InputTagHelper2 __InputTagHelper2 = null; + #line hidden + public BasicTagHelpers() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + __PTagHelper = CreateTagHelper(); + __PTagHelper = CreateTagHelper(); + __InputTagHelper = CreateTagHelper(); + __InputTagHelper.Type = "text"; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; + __InputTagHelper = CreateTagHelper(); + __InputTagHelper.Type = "checkbox"; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; + __InputTagHelper2.Checked = true; + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs new file mode 100644 index 0000000000..28c9ac70b7 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ComplexTagHelpers.DesignTime.cs @@ -0,0 +1,133 @@ +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class ComplexTagHelpers + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + string __tagHelperDirectiveSyntaxHelper = null; + __tagHelperDirectiveSyntaxHelper = +#line 1 "ComplexTagHelpers.cshtml" + "something" + +#line default +#line hidden + ; + #pragma warning restore 219 + } + #line hidden + private PTagHelper __PTagHelper = null; + private InputTagHelper __InputTagHelper = null; + private InputTagHelper2 __InputTagHelper2 = null; + #line hidden + public ComplexTagHelpers() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { +#line 3 "ComplexTagHelpers.cshtml" +if (true) +{ + var checkbox = "checkbox"; + + +#line default +#line hidden + + __PTagHelper = CreateTagHelper(); +#line 8 "ComplexTagHelpers.cshtml" +__o = DateTime.Now; + +#line default +#line hidden +#line 10 "ComplexTagHelpers.cshtml" + + +#line default +#line hidden + +#line 10 "ComplexTagHelpers.cshtml" + if (false) + { + +#line default +#line hidden + + __PTagHelper = CreateTagHelper(); + __InputTagHelper = CreateTagHelper(); + __InputTagHelper.Type = "text"; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; +#line 13 "ComplexTagHelpers.cshtml" + } + else + { + +#line default +#line hidden + + __PTagHelper = CreateTagHelper(); + __InputTagHelper = CreateTagHelper(); +#line 16 "ComplexTagHelpers.cshtml" +__o = checkbox; + +#line default +#line hidden + __InputTagHelper.Type = string.Empty; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; + __InputTagHelper2.Checked = true; + __InputTagHelper = CreateTagHelper(); +#line 17 "ComplexTagHelpers.cshtml" +__o = true ? "checkbox" : "anything"; + +#line default +#line hidden + __InputTagHelper.Type = string.Empty; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; + __InputTagHelper = CreateTagHelper(); +#line 18 "ComplexTagHelpers.cshtml" +if(true) { + +#line default +#line hidden + +#line 18 "ComplexTagHelpers.cshtml" +} else { + +#line default +#line hidden + +#line 18 "ComplexTagHelpers.cshtml" +} + +#line default +#line hidden + + __InputTagHelper.Type = string.Empty; + __InputTagHelper2 = CreateTagHelper(); + __InputTagHelper2.Type = __InputTagHelper.Type; +#line 19 "ComplexTagHelpers.cshtml" + } + +#line default +#line hidden + +#line 22 "ComplexTagHelpers.cshtml" +} + +#line default +#line hidden + + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ContentBehaviorTagHelpers.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ContentBehaviorTagHelpers.DesignTime.cs new file mode 100644 index 0000000000..58140f8f3c --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/ContentBehaviorTagHelpers.DesignTime.cs @@ -0,0 +1,45 @@ +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class ContentBehaviorTagHelpers + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + string __tagHelperDirectiveSyntaxHelper = null; + __tagHelperDirectiveSyntaxHelper = +#line 1 "ContentBehaviorTagHelpers.cshtml" + "something" + +#line default +#line hidden + ; + #pragma warning restore 219 + } + #line hidden + private ModifyTagHelper __ModifyTagHelper = null; + private NoneTagHelper __NoneTagHelper = null; + private AppendTagHelper __AppendTagHelper = null; + private PrependTagHelper __PrependTagHelper = null; + private ReplaceTagHelper __ReplaceTagHelper = null; + #line hidden + public ContentBehaviorTagHelpers() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + __ModifyTagHelper = CreateTagHelper(); + __NoneTagHelper = CreateTagHelper(); + __AppendTagHelper = CreateTagHelper(); + __PrependTagHelper = CreateTagHelper(); + __ReplaceTagHelper = CreateTagHelper(); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.DesignTime.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.DesignTime.cs new file mode 100644 index 0000000000..16fb5c4ed4 --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.DesignTime.cs @@ -0,0 +1,38 @@ +namespace TestOutput +{ + using Microsoft.AspNet.Razor.Runtime.TagHelpers; + using System; + using System.Threading.Tasks; + + public class SingleTagHelper + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + string __tagHelperDirectiveSyntaxHelper = null; + __tagHelperDirectiveSyntaxHelper = +#line 1 "SingleTagHelper.cshtml" + "something" + +#line default +#line hidden + ; + #pragma warning restore 219 + } + #line hidden + private PTagHelper __PTagHelper = null; + #line hidden + public SingleTagHelper() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + __PTagHelper = CreateTagHelper(); + __PTagHelper.Age = 1337; + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.cs b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.cs index 45a3fb4fd2..5d5aa2a289 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.cs +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Output/SingleTagHelper.cs @@ -1,4 +1,4 @@ -#pragma checksum "SingleTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "61bf4cc89584cdbbac4478b202fe04797ddeb68a" +#pragma checksum "SingleTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a4d3eab407a97d5beebc7d3a319223ece03f3733" namespace TestOutput { using Microsoft.AspNet.Razor.Runtime.TagHelpers; @@ -27,8 +27,8 @@ namespace TestOutput __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p"); __PTagHelper = CreateTagHelper(); __tagHelperExecutionContext.Add(__PTagHelper); - __PTagHelper.Foo = 1337; - __tagHelperExecutionContext.AddTagHelperAttribute("foo", __PTagHelper.Foo); + __PTagHelper.Age = 1337; + __tagHelperExecutionContext.AddTagHelperAttribute("age", __PTagHelper.Age); __tagHelperExecutionContext.AddHtmlAttribute("class", "Hello World"); __tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result; WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag()); diff --git a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/SingleTagHelper.cshtml b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/SingleTagHelper.cshtml index 32411e496b..5040d4f003 100644 --- a/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/SingleTagHelper.cshtml +++ b/test/Microsoft.AspNet.Razor.Test/TestFiles/CodeGenerator/CS/Source/SingleTagHelper.cshtml @@ -1,3 +1,3 @@ @addtaghelper "something" -

Body of Tag

\ No newline at end of file +

Body of Tag

\ No newline at end of file