Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test')
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/BoundAttributeDescriptorExtensionsTest.cs279
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CSharpCodeWriterTest.cs339
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CodeTargetTest.cs68
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetBuilderTest.cs46
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetTest.cs174
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs393
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DesignTimeNodeWriterTest.cs488
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/LiteralRuntimeNodeWriterTest.cs45
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeNodeWriterTest.cs599
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriterTest.cs125
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultBoundAttributeDescriptorBuilderTest.cs47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultDocumentClassifierPassTest.cs60
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultItemCollectionTest.cs54
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCSharpLoweringPhaseTest.cs87
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCodeDocumentTest.cs47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDiagnosticTest.cs217
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDirectiveClassifierPhaseTest.cs102
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDocumentClassifierPhaseTest.cs102
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineBuilderTest.cs42
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineTest.cs72
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs519
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs298
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorOptimizationPhaseTest.cs102
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs93
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineBuilderTest.cs65
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineIntegrationTest.cs95
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineTest.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectFileSystemTest.cs263
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectItemTest.cs61
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorSyntaxTreePhaseTest.cs94
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorTagHelperBinderPhaseTest.cs930
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRequiredAttributeDescriptorBuilderTest.cs44
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorBuilderExtensionsTest.cs122
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorTest.cs150
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveRemovalOptimizationPassTest.cs135
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs66
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DocumentClassifierPassBaseTest.cs300
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultMetadataIdentifierFeatureTest.cs72
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperOptimizationPassTest.cs128
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs1210
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DesignTimeDirectiveTargetExtensionTest.cs217
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/FunctionsDirectivePassTest.cs104
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/InheritsDirectivePassTest.cs97
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributePassTest.cs362
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributeTargetExtensionTest.cs123
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/PreallocatedAttributeTargetExtensionTest.cs276
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionDirectivePassTest.cs106
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionTargetExtensionTest.cs80
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs51
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlConventionsTest.cs39
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlNodeOptimizationPassTest.cs53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/BasicIntegrationTest.cs117
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/CodeGenerationIntegrationTest.cs987
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/ExtensibleDirectiveTest.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/HtmlAttributeIntegrationTest.cs38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs103
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TagHelpersIntegrationTest.cs124
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TestTagHelperDescriptors.cs637
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DefaultRazorIntermediateNodeBuilderTest.cs217
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DocumentIntermediateNodeExtensionsTest.cs113
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/ExtensionIntermediateNodeTest.cs92
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeReferenceTest.cs510
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeWalkerTest.cs140
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/LargeTextSourceDocumentTest.cs172
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BaselineWriter.cs46
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTest.cs118
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs144
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpBlockTest.cs1256
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs1965
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpErrorTest.cs654
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpExplicitExpressionTest.cs139
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpImplicitExpressionTest.cs282
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpLanguageCharacteristicsTest.cs20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpNestedStatementsTest.cs104
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs390
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpReservedWordsTest.cs40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs766
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs246
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpStatementTest.cs432
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTemplateTest.cs321
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpToMarkupSwitchTest.cs691
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerCommentTest.cs94
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerIdentifierTest.cs170
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerLiteralTest.cs287
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerOperatorsTest.cs296
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTest.cs106
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTestBase.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpVerbatimBlockTest.cs134
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpWhitespaceHandlingTest.cs34
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CodeParserTestBase.cs79
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlCodeParserTestBase.cs20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlMarkupParserTestBase.cs20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveCSharpTokenizerTest.cs47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveHtmlTokenizerTest.cs41
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DisposableActionTest.cs25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ExceptionHelpers.cs16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlAttributeTest.cs707
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs657
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs803
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlErrorTest.cs110
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlMarkupParserTests.cs226
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlParserTestUtils.cs43
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTagsTest.cs206
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs455
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTest.cs163
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTestBase.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/LineTrackingStringBufferTest.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MarkupParserTestBase.cs25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MiscUtils.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RazorParserTest.cs86
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SourceLocationTrackerTest.cs214
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SpanTest.cs78
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs4014
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockTest.cs207
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs4346
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperRewritingTestBase.cs75
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TextReaderExtensionsTest.cs113
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerLookaheadTest.cs221
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerTestBase.cs72
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/WhiteSpaceRewriterTest.cs40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Microsoft.AspNetCore.Razor.Language.Test.csproj30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Properties/AssemblyInfo.cs6
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentExtensionsTest.cs214
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentTest.cs61
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticDescriptorTest.cs78
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticTest.cs45
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineBuilderExtensionsTest.cs98
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs233
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineBuilderExtensionsTest.cs103
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineFeatureBaseTest.cs34
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineTest.cs85
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectItemTest.cs104
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectTest.cs333
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSourceDocumentTest.cs219
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSyntaxTreeTest.cs79
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorTemplateEngineTest.cs359
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceChangeTest.cs197
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceLocationTest.cs110
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceSpanTest.cs117
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StreamSourceDocumentTest.cs200
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StringSourceDocumentTest.cs516
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperBinderTest.cs524
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorBuilderTest.cs38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorExtensionsTest.cs64
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperMatchingConventionsTest.cs156
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Home.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/About/About.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/_ViewImports.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/_ViewImports.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/_ViewImports.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt6
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt6
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.codegen.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.ir.txt14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.codegen.cs51
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.ir.txt82
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.mappings.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.codegen.cs126
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.ir.txt65
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.codegen.cs95
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.ir.txt130
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.mappings.txt95
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.codegen.cs104
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.ir.txt125
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.codegen.cs37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.ir.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.mappings.txt0
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.codegen.cs36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.ir.txt16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml9
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.codegen.cs49
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.ir.txt84
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.mappings.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.codegen.cs43
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.ir.txt59
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.mappings.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.codegen.cs82
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.ir.txt46
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.codegen.cs115
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.ir.txt55
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.codegen.cs129
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.ir.txt69
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.codegen.cs138
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.ir.txt101
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.mappings.txt139
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.codegen.cs136
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.ir.txt112
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml43
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.codegen.cs81
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.ir.txt45
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.mappings.txt88
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.codegen.cs84
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.ir.txt48
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.codegen.cs23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.ir.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.codegen.cs18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.ir.txt8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.codegen.cs41
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.mappings.txt26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.codegen.cs37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.ir.txt18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.codegen.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.ir.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.mappings.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.codegen.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.ir.txt8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.codegen.cs207
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.ir.txt298
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.mappings.txt293
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.codegen.cs493
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.ir.txt299
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.codegen.cs102
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.ir.txt120
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.mappings.txt138
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.codegen.cs108
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.ir.txt107
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.codegen.cs242
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.ir.txt137
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.codegen.cs68
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.ir.txt63
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.mappings.txt49
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml7
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.codegen.cs57
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.ir.txt96
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.mappings.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.codegen.cs146
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.ir.txt69
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.codegen.cs38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.ir.txt32
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.codegen.cs65
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.codegen.cs185
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.ir.txt133
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.mappings.txt155
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.codegen.cs310
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.ir.txt127
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.codegen.cs53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.diagnostics.txt3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.ir.txt67
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.mappings.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.codegen.cs114
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.diagnostics.txt3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.ir.txt51
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.codegen.cs23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.codegen.cs19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.codegen.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.codegen.cs31
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.ir.txt17
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.mappings.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.codegen.cs23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.ir.txt17
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.codegen.cs25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml11
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.codegen.cs79
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.ir.txt74
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.mappings.txt49
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.codegen.cs164
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.ir.txt68
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.codegen.cs47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.ir.txt69
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.mappings.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.codegen.cs83
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.ir.txt63
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.codegen.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.codegen.cs29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.ir.txt18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.codegen.cs29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.ir.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.codegen.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.codegen.cs70
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.ir.txt40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.mappings.txt58
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.codegen.cs68
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.ir.txt36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml7
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.codegen.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.mappings.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.codegen.cs39
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.ir.txt21
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.mappings.txt29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.codegen.cs34
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.ir.txt16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.codegen.cs29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.mappings.txt14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.codegen.cs23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.codegen.cs22
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.mappings.txt0
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.codegen.cs19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.codegen.cs22
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.mappings.txt0
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.codegen.cs19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.codegen.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.codegen.cs39
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.ir.txt22
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.mappings.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.codegen.cs35
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.ir.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs70
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt84
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt65
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt54
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.codegen.cs28
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.codegen.cs52
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.ir.txt16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.codegen.cs31
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.ir.txt16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.codegen.cs24
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.ir.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.codegen.cs46
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.ir.txt29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.mappings.txt25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.codegen.cs48
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.codegen.cs146
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.ir.txt111
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.mappings.txt153
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.codegen.cs144
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.ir.txt123
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.codegen.cs40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.ir.txt22
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.mappings.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.codegen.cs36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.ir.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.codegen.cs45
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.ir.txt108
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.codegen.cs188
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.ir.txt89
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.codegen.cs44
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.ir.txt27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.mappings.txt35
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.codegen.cs36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.ir.txt25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.codegen.cs40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.ir.txt17
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.mappings.txt21
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.codegen.cs36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.codegen.cs56
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.ir.txt87
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.mappings.txt29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.codegen.cs106
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.ir.txt80
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.codegen.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.ir.txt48
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.codegen.cs89
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.ir.txt37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.codegen.cs140
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.ir.txt103
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.mappings.txt148
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.codegen.cs137
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.ir.txt113
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml11
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.codegen.cs72
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.ir.txt45
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.mappings.txt75
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.codegen.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.ir.txt40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.codegen.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.diagnostics.txt3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.ir.txt26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.mappings.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.codegen.cs25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.diagnostics.txt3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.ir.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.codegen.cs31
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.ir.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.mappings.txt13
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.codegen.cs27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.diagnostics.txt2
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.ir.txt8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.codegen.cs117
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.ir.txt136
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.mappings.txt80
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.codegen.cs260
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.ir.txt117
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.codegen.cs53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt42
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.mappings.txt47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.codegen.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.ir.txt14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml17
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs72
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt59
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt44
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs70
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.codegen.cs29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.ir.txt35
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.codegen.cs56
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.ir.txt26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.codegen.cs35
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.ir.txt18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.mappings.txt16
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.codegen.cs30
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.ir.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.codegen.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.ir.txt27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.codegen.cs59
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.ir.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.codegen.cs33
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.ir.txt27
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.codegen.cs59
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.ir.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml237
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.codegen.cs36
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.ir.txt953
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.codegen.cs267
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.ir.txt945
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.codegen.cs56
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.diagnostics.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.ir.txt140
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.mappings.txt25
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.codegen.cs197
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.diagnostics.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.ir.txt126
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml14
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.codegen.cs102
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.ir.txt54
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.codegen.cs34
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.ir.txt31
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.mappings.txt10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.codegen.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.codegen.cs38
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.ir.txt34
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.mappings.txt15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.codegen.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.codegen.cs64
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.ir.txt57
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.mappings.txt47
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.codegen.cs121
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.ir.txt50
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml15
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.codegen.cs54
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt75
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.mappings.txt20
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs134
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt59
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml53
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.codegen.cs156
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.ir.txt149
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.mappings.txt169
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.codegen.cs188
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.ir.txt147
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.codegen.cs80
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.ir.txt105
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.mappings.txt116
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.codegen.cs186
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.diagnostics.txt1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.ir.txt92
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml3
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.codegen.cs31
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.ir.txt17
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.mappings.txt19
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.codegen.cs23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml10
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.codegen.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.ir.txt42
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.mappings.txt40
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.codegen.cs62
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.ir.txt29
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.codegen.cs26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.ir.txt12
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.mappings.txt5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt22
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs18
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml1
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt37
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.cshtml5
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt26
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.cshtml4
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt23
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/Source/BasicMarkup.cshtml8
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/nested-1000.html2002
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestRazorProject.cs41
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/VirtualRazorProjectFileSystemTest.cs400
-rw-r--r--src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/xunit.runner.json4
629 files changed, 64198 insertions, 0 deletions
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/BoundAttributeDescriptorExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/BoundAttributeDescriptorExtensionsTest.cs
new file mode 100644
index 0000000000..8b1c290d3a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/BoundAttributeDescriptorExtensionsTest.cs
@@ -0,0 +1,279 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class BoundAttributeDescriptorExtensionsTest
+ {
+ [Fact]
+ public void GetPropertyName_ReturnsPropertyName()
+ {
+ // Arrange
+ var expectedPropertyName = "IntProperty";
+
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName(expectedPropertyName)
+ .TypeName(typeof(int).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var propertyName = descriptor.GetPropertyName();
+
+ // Assert
+ Assert.Equal(expectedPropertyName, propertyName);
+ }
+
+ [Fact]
+ public void GetPropertyName_ReturnsNullIfNoPropertyName()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .TypeName(typeof(int).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var propertyName = descriptor.GetPropertyName();
+
+ // Assert
+ Assert.Null(propertyName);
+ }
+
+ [Fact]
+ public void IsDefaultKind_ReturnsTrue_IfKindIsDefault()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("IntProperty")
+ .TypeName(typeof(int).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var isDefault = descriptor.IsDefaultKind();
+
+ // Assert
+ Assert.True(isDefault);
+ }
+
+ [Fact]
+ public void IsDefaultKind_ReturnsFalse_IfKindIsNotDefault()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder("other-kind", "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, "other-kind");
+ builder
+ .Name("test")
+ .PropertyName("IntProperty")
+ .TypeName(typeof(int).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var isDefault = descriptor.IsDefaultKind();
+
+ // Assert
+ Assert.False(isDefault);
+ }
+
+ [Fact]
+ public void ExpectsStringValue_ReturnsTrue_ForStringProperty()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName(typeof(string).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsStringValue("test");
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void ExpectsStringValue_ReturnsFalse_ForNonStringProperty()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName(typeof(bool).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsStringValue("test");
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void ExpectsStringValue_ReturnsTrue_StringIndexerAndNameMatch()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName("System.Collection.Generic.IDictionary<string, string>")
+ .AsDictionary("prefix-test-", typeof(string).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsStringValue("prefix-test-key");
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void ExpectsStringValue_ReturnsFalse_StringIndexerAndNameMismatch()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName("System.Collection.Generic.IDictionary<string, string>")
+ .AsDictionary("prefix-test-", typeof(string).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsStringValue("test");
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void ExpectsBooleanValue_ReturnsTrue_ForBooleanProperty()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName(typeof(bool).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsBooleanValue("test");
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void ExpectsBooleanValue_ReturnsFalse_ForNonBooleanProperty()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName(typeof(int).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsBooleanValue("test");
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void ExpectsBooleanValue_ReturnsTrue_BooleanIndexerAndNameMatch()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName("System.Collection.Generic.IDictionary<string, bool>")
+ .AsDictionary("prefix-test-", typeof(bool).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsBooleanValue("prefix-test-key");
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void ExpectsBooleanValue_ReturnsFalse_BooleanIndexerAndNameMismatch()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("test")
+ .PropertyName("BoundProp")
+ .TypeName("System.Collection.Generic.IDictionary<string, bool>")
+ .AsDictionary("prefix-test-", typeof(bool).FullName);
+
+ var descriptor = builder.Build();
+
+ // Act
+ var result = descriptor.ExpectsBooleanValue("test");
+
+ // Assert
+ Assert.False(result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CSharpCodeWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CSharpCodeWriterTest.cs
new file mode 100644
index 0000000000..e0bfa57ca1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CSharpCodeWriterTest.cs
@@ -0,0 +1,339 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class CSharpCodeWriterTest
+ {
+ // The length of the newline string written by writer.WriteLine.
+ private static readonly int WriterNewLineLength = Environment.NewLine.Length;
+
+ public static IEnumerable<object[]> NewLines
+ {
+ get
+ {
+ return new object[][]
+ {
+ new object[] { "\r" },
+ new object[] { "\n" },
+ new object[] { "\r\n" },
+ };
+ }
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithWrite()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234");
+
+ // Assert
+ var location = writer.Location;
+ var expected = new SourceLocation(absoluteIndex: 4, lineIndex: 0, characterIndex: 4);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithIndent()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteLine();
+ writer.Indent(size: 3);
+
+ // Assert
+ var location = writer.Location;
+ var expected = new SourceLocation(absoluteIndex: 3 + WriterNewLineLength, lineIndex: 1, characterIndex: 3);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithWriteLine()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteLine("1234");
+
+ // Assert
+ var location = writer.Location;
+
+ var expected = new SourceLocation(absoluteIndex: 4 + WriterNewLineLength, lineIndex: 1, characterIndex: 0);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Theory]
+ [MemberData(nameof(NewLines))]
+ public void CSharpCodeWriter_TracksPosition_WithWriteLine_WithNewLineInContent(string newLine)
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteLine("1234" + newLine + "12");
+
+ // Assert
+ var location = writer.Location;
+
+ var expected = new SourceLocation(
+ absoluteIndex: 6 + newLine.Length + WriterNewLineLength,
+ lineIndex: 2,
+ characterIndex: 0);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Theory]
+ [MemberData(nameof(NewLines))]
+ public void CSharpCodeWriter_TracksPosition_WithWrite_WithNewlineInContent(string newLine)
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234" + newLine + "123" + newLine + "12");
+
+ // Assert
+ var location = writer.Location;
+
+ var expected = new SourceLocation(
+ absoluteIndex: 9 + newLine.Length + newLine.Length,
+ lineIndex: 2,
+ characterIndex: 2);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithWrite_WithNewlineInContent_RepeatedN()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\n\n123");
+
+ // Assert
+ var location = writer.Location;
+
+ var expected = new SourceLocation(
+ absoluteIndex: 9,
+ lineIndex: 2,
+ characterIndex: 3);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithWrite_WithMixedNewlineInContent()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\r123\r\n12\n1");
+
+ // Assert
+ var location = writer.Location;
+
+ var expected = new SourceLocation(
+ absoluteIndex: 14,
+ lineIndex: 3,
+ characterIndex: 1);
+
+ Assert.Equal(expected, location);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithNewline_SplitAcrossWrites()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\r");
+ var location1 = writer.Location;
+
+ writer.Write("\n");
+ var location2 = writer.Location;
+
+ // Assert
+ var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected1, location1);
+
+ var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected2, location2);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_R()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\r");
+ var location1 = writer.Location;
+
+ writer.Write("\r");
+ var location2 = writer.Location;
+
+ // Assert
+ var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected1, location1);
+
+ var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
+ Assert.Equal(expected2, location2);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_N()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\n");
+ var location1 = writer.Location;
+
+ writer.Write("\n");
+ var location2 = writer.Location;
+
+ // Assert
+ var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected1, location1);
+
+ var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
+ Assert.Equal(expected2, location2);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_Reversed()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("1234\n");
+ var location1 = writer.Location;
+
+ writer.Write("\r");
+ var location2 = writer.Location;
+
+ // Assert
+ var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected1, location1);
+
+ var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
+ Assert.Equal(expected2, location2);
+ }
+
+ [Fact]
+ public void CSharpCodeWriter_TracksPosition_WithNewline_SplitAcrossWrites_AtBeginning()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.Write("\r");
+ var location1 = writer.Location;
+
+ writer.Write("\n");
+ var location2 = writer.Location;
+
+ // Assert
+ var expected1 = new SourceLocation(absoluteIndex: 1, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected1, location1);
+
+ var expected2 = new SourceLocation(absoluteIndex: 2, lineIndex: 1, characterIndex: 0);
+ Assert.Equal(expected2, location2);
+ }
+
+ [Fact]
+ public void WriteLineNumberDirective_UsesFilePath_FromSourceLocation()
+ {
+ // Arrange
+ var filePath = "some-path";
+ var mappingLocation = new SourceSpan(filePath, 10, 4, 3, 9);
+
+ var writer = new CodeWriter();
+ var expected = $"#line 5 \"{filePath}\"" + writer.NewLine;
+
+ // Act
+ writer.WriteLineNumberDirective(mappingLocation);
+ var code = writer.GenerateCode();
+
+ // Assert
+ Assert.Equal(expected, code);
+ }
+
+ [Fact]
+ public void WriteField_WritesFieldDeclaration()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteField(new[] { "private" }, "global::System.String", "_myString");
+
+ // Assert
+ var output = writer.GenerateCode();
+ Assert.Equal("private global::System.String _myString;" + Environment.NewLine, output);
+ }
+
+ [Fact]
+ public void WriteField_WithModifiers_WritesFieldDeclaration()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteField(new[] { "private", "readonly", "static" }, "global::System.String", "_myString");
+
+ // Assert
+ var output = writer.GenerateCode();
+ Assert.Equal("private readonly static global::System.String _myString;" + Environment.NewLine, output);
+ }
+
+ [Fact]
+ public void WriteAutoPropertyDeclaration_WritesPropertyDeclaration()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteAutoPropertyDeclaration(new[] { "public" }, "global::System.String", "MyString");
+
+ // Assert
+ var output = writer.GenerateCode();
+ Assert.Equal("public global::System.String MyString { get; set; }" + Environment.NewLine, output);
+ }
+
+ [Fact]
+ public void WriteAutoPropertyDeclaration_WithModifiers_WritesPropertyDeclaration()
+ {
+ // Arrange
+ var writer = new CodeWriter();
+
+ // Act
+ writer.WriteAutoPropertyDeclaration(new[] { "public", "static" }, "global::System.String", "MyString");
+
+ // Assert
+ var output = writer.GenerateCode();
+ Assert.Equal("public static global::System.String MyString { get; set; }" + Environment.NewLine, output);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CodeTargetTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CodeTargetTest.cs
new file mode 100644
index 0000000000..7626e3369a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/CodeTargetTest.cs
@@ -0,0 +1,68 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class CodeTargetTest
+ {
+ [Fact]
+ public void CreateDefault_CreatesDefaultCodeTarget()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+
+ // Assert
+ Assert.IsType<DefaultCodeTarget>(target);
+ }
+
+ [Fact]
+ public void CreateDefault_CallsDelegate()
+ {
+ // Arrange
+ var wasCalled = false;
+ Action<CodeTargetBuilder> @delegate = (b) => { wasCalled = true; };
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ CodeTarget.CreateDefault(codeDocument, options, @delegate);
+
+ // Assert
+ Assert.True(wasCalled);
+ }
+
+ [Fact]
+ public void CreateDefault_AllowsNullDelegate()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ CodeTarget.CreateDefault(codeDocument, options, configure: null);
+
+ // Assert (does not throw)
+ }
+
+ [Fact]
+ public void CreateEmpty_AllowsNullDelegate()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ CodeTarget.CreateDefault(codeDocument, options, configure: null);
+
+ // Assert (does not throw)
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetBuilderTest.cs
new file mode 100644
index 0000000000..95f124300a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetBuilderTest.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class DefaultCodeTargetBuilderTest
+ {
+ [Fact]
+ public void Build_CreatesDefaultCodeTarget()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var builder = new DefaultCodeTargetBuilder(codeDocument, options);
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension1(),
+ new MyExtension2(),
+ };
+
+ for (var i = 0; i < extensions.Length; i++)
+ {
+ builder.TargetExtensions.Add(extensions[i]);
+ }
+
+ // Act
+ var result = builder.Build();
+
+ // Assert
+ var target = Assert.IsType<DefaultCodeTarget>(result);
+ Assert.Equal(extensions, target.Extensions);
+ }
+
+ private class MyExtension1 : ICodeTargetExtension
+ {
+ }
+
+ private class MyExtension2 : ICodeTargetExtension
+ {
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetTest.cs
new file mode 100644
index 0000000000..05756c09bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultCodeTargetTest.cs
@@ -0,0 +1,174 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class DefaultCodeTargetTest
+ {
+ [Fact]
+ public void Constructor_CreatesDefensiveCopy()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension1(),
+ };
+
+ // Act
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Assert
+ Assert.NotSame(extensions, target);
+ }
+
+ [Fact]
+ public void CreateWriter_DesignTime_CreatesDesignTimeNodeWriter()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDesignTimeDefault();
+ var target = new DefaultCodeTarget(options, Enumerable.Empty<ICodeTargetExtension>());
+
+ // Act
+ var writer = target.CreateNodeWriter();
+
+ // Assert
+ Assert.IsType<DesignTimeNodeWriter>(writer);
+ }
+
+ [Fact]
+ public void CreateWriter_Runtime_CreatesRuntimeNodeWriter()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+ var target = new DefaultCodeTarget(options, Enumerable.Empty<ICodeTargetExtension>());
+
+ // Act
+ var writer = target.CreateNodeWriter();
+
+ // Assert
+ Assert.IsType<RuntimeNodeWriter>(writer);
+ }
+
+ [Fact]
+ public void HasExtension_ReturnsTrue_WhenExtensionFound()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension1(),
+ };
+
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Act
+ var result = target.HasExtension<MyExtension1>();
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void HasExtension_ReturnsFalse_WhenExtensionNotFound()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension2(),
+ };
+
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Act
+ var result = target.HasExtension<MyExtension1>();
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void GetExtension_ReturnsExtension_WhenExtensionFound()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension1(),
+ };
+
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Act
+ var result = target.GetExtension<MyExtension1>();
+
+ // Assert
+ Assert.Same(extensions[1], result);
+ }
+
+ [Fact]
+ public void GetExtension_ReturnsFirstMatch_WhenExtensionFound()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension1(),
+ new MyExtension2(),
+ new MyExtension1(),
+ };
+
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Act
+ var result = target.GetExtension<MyExtension1>();
+
+ // Assert
+ Assert.Same(extensions[1], result);
+ }
+
+
+ [Fact]
+ public void GetExtension_ReturnsNull_WhenExtensionNotFound()
+ {
+ // Arrange
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var extensions = new ICodeTargetExtension[]
+ {
+ new MyExtension2(),
+ new MyExtension2(),
+ };
+
+ var target = new DefaultCodeTarget(options, extensions);
+
+ // Act
+ var result = target.GetExtension<MyExtension1>();
+
+ // Assert
+ Assert.Null(result);
+ }
+
+ private class MyExtension1 : ICodeTargetExtension
+ {
+ }
+
+ private class MyExtension2 : ICodeTargetExtension
+ {
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs
new file mode 100644
index 0000000000..3537eea4f6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DefaultDocumentWriterTest.cs
@@ -0,0 +1,393 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class DefaultDocumentWriterTest
+ {
+ [Fact] // This test covers the whole process including actual hashing.
+ public void WriteDocument_EndToEnd_WritesChecksumAndMarksAutoGenerated()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_SHA1_WritesChecksumAndMarksAutoGenerated()
+ {
+ // Arrange
+ var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
+
+ var sourceDocument = Mock.Of<RazorSourceDocument>(d =>
+ d.FilePath == "test.cshtml" &&
+ d.GetChecksum() == checksumBytes &&
+ d.GetChecksumAlgorithm() == "SHA1");
+
+ var document = new DocumentIntermediateNode();
+
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""74657374""
+// <auto-generated/>
+#pragma warning disable 1591
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_SHA256_WritesChecksumAndMarksAutoGenerated()
+ {
+ // Arrange
+ var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
+
+ var sourceDocument = Mock.Of<RazorSourceDocument>(d =>
+ d.FilePath == "test.cshtml" &&
+ d.GetChecksum() == checksumBytes &&
+ d.GetChecksumAlgorithm() == "SHA256");
+
+ var document = new DocumentIntermediateNode();
+
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{8829d00f-11b8-4213-878b-770e8597ac16}"" ""74657374""
+// <auto-generated/>
+#pragma warning disable 1591
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_UnsupportedChecksumAlgorithm_Throws()
+ {
+ // Arrange
+ var checksumBytes = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', };
+
+ var sourceDocument = Mock.Of<RazorSourceDocument>(d =>
+ d.FilePath == "test.cshtml" &&
+ d.GetChecksum() == checksumBytes &&
+ d.GetChecksumAlgorithm() == "SHA3");
+
+ var document = new DocumentIntermediateNode();
+
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() =>
+ {
+ var result = writer.WriteDocument(codeDocument, document);
+ });
+ Assert.Equal(
+ "The hash algorithm 'SHA3' is not supported for checksum generation. Supported algorithms are: 'SHA1 SHA256'. " +
+ "Set 'RazorCodeGenerationOptions.SuppressChecksum' to 'True' to suppress automatic checksum generation.",
+ exception.Message);
+ }
+
+
+
+ [Fact]
+ public void WriteDocument_Empty_SuppressChecksumTrue_DoesnotWriteChecksum()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var optionsBuilder = new DefaultRazorCodeGenerationOptionsBuilder(designTime: false)
+ {
+ SuppressChecksum = true
+ };
+ var options = optionsBuilder.Build();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"// <auto-generated/>
+#pragma warning disable 1591
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_WritesNamespace()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(new NamespaceDeclarationIntermediateNode()
+ {
+ Content = "TestNamespace",
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+namespace TestNamespace
+{
+ #line hidden
+}
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_WritesClass()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(new ClassDeclarationIntermediateNode()
+ {
+ Modifiers =
+ {
+ "internal"
+ },
+ BaseType = "TestBase",
+ Interfaces = new List<string> { "IFoo", "IBar", },
+ TypeParameters = new List<TypeParameter>
+ {
+ new TypeParameter() { ParameterName = "TKey", },
+ new TypeParameter() { ParameterName = "TValue", },
+ },
+ ClassName = "TestClass",
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+internal class TestClass<TKey, TValue> : TestBase, IFoo, IBar
+{
+}
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_WritesMethod()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(new MethodDeclarationIntermediateNode()
+ {
+ Modifiers =
+ {
+ "internal",
+ "virtual",
+ "async",
+ },
+ MethodName = "TestMethod",
+ Parameters =
+ {
+ new MethodParameter()
+ {
+ Modifiers =
+ {
+ "readonly",
+ "ref",
+ },
+ ParameterName = "a",
+ TypeName = "int",
+ },
+ new MethodParameter()
+ {
+ ParameterName = "b",
+ TypeName = "string",
+ }
+ },
+ ReturnType = "string",
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+#pragma warning disable 1998
+internal virtual async string TestMethod(readonly ref int a, string b)
+{
+}
+#pragma warning restore 1998
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_WritesField()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(new FieldDeclarationIntermediateNode()
+ {
+ Modifiers =
+ {
+ "internal",
+ "readonly",
+ },
+ FieldName = "_foo",
+ FieldType = "string",
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+internal readonly string _foo;
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDocument_WritesProperty()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(new PropertyDeclarationIntermediateNode()
+ {
+ Modifiers =
+ {
+ "internal",
+ "virtual",
+ },
+ PropertyName = "Foo",
+ PropertyType = "string",
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ var target = CodeTarget.CreateDefault(codeDocument, options);
+ var writer = new DefaultDocumentWriter(target, options);
+
+ // Act
+ var result = writer.WriteDocument(codeDocument, document);
+
+ // Assert
+ var csharp = result.GeneratedCode;
+ Assert.Equal(
+@"#pragma checksum ""test.cshtml"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""da39a3ee5e6b4b0d3255bfef95601890afd80709""
+// <auto-generated/>
+#pragma warning disable 1591
+internal virtual string Foo { get; set; }
+#pragma warning restore 1591
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DesignTimeNodeWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DesignTimeNodeWriterTest.cs
new file mode 100644
index 0000000000..c602375095
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/DesignTimeNodeWriterTest.cs
@@ -0,0 +1,488 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class DesignTimeNodeWriterTest
+ {
+ [Fact]
+ public void WriteUsingDirective_NoSource_WritesContent()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new UsingDirectiveIntermediateNode()
+ {
+ Content = "System",
+ };
+
+ // Act
+ writer.WriteUsingDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"using System;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteUsingDirective_WithSource_WritesContentWithLinePragmaAndMapping()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var sourceDocument = TestRazorSourceDocument.Create("@using System;");
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var originalSpan = new SourceSpan("test.cshtml", 0, 0, 0, 6);
+ var generatedSpan = new SourceSpan(null, 21 + Environment.NewLine.Length, 1, 0, 6);
+ var expectedSourceMapping = new SourceMapping(originalSpan, generatedSpan);
+ var node = new UsingDirectiveIntermediateNode()
+ {
+ Content = "System",
+ Source = originalSpan,
+ };
+
+ // Act
+ writer.WriteUsingDirective(context, node);
+
+ // Assert
+ var mapping = Assert.Single(((DefaultCodeRenderingContext)context).SourceMappings);
+ Assert.Equal(expectedSourceMapping, mapping);
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+using System;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_SkipsLinePragma_WithoutSource()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpExpressionIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__o = i++;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WritesLinePragma_WithSource()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpExpressionIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
+ };
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+__o = i++;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WithExtensionNode_WritesPadding()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpExpressionIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i",
+ Kind = TokenKind.CSharp,
+ });
+ builder.Add(new MyExtensionIntermediateNode());
+ builder.Add(new IntermediateToken()
+ {
+ Content = "++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__o = iRender Children
+++;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WithSource_WritesPadding()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpExpressionIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 8, 0, 8, 3),
+ };
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i",
+ Kind = TokenKind.CSharp,
+ });
+ builder.Add(new MyExtensionIntermediateNode());
+ builder.Add(new IntermediateToken()
+ {
+ Content = "++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ __o = iRender Children
+++;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WhitespaceContent_DoesNothing()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpCodeIntermediateNode();
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = " \t"
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Empty(csharp);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WhitespaceContentWithSource_WritesContent()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpCodeIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
+ };
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = " "
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_SkipsLinePragma_WithoutSource()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpCodeIntermediateNode();
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = "if (true) { }"
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"if (true) { }
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WritesLinePragma_WithSource()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpCodeIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 13),
+ };
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = "if (true) { }",
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+if (true) { }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WritesPadding_WithSource()
+ {
+ // Arrange
+ var writer = new DesignTimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new CSharpCodeIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 17),
+ };
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = " if (true) { }",
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ if (true) { }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpressionAttributeValue_RendersCorrectly()
+ {
+ var writer = new DesignTimeNodeWriter();
+
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpExpressionAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateDesignTime(source: sourceDocument);
+
+ // Act
+ writer.WriteCSharpExpressionAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ __o = false;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCodeAttributeValue_RendersCorrectly()
+ {
+ var writer = new DesignTimeNodeWriter();
+ var content = "<input checked=\"hello-world @if(@true){ }\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpCodeAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateDesignTime(source: sourceDocument);
+
+ // Act
+ writer.WriteCSharpCodeAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ if(@true){ }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCodeAttributeValue_WithExpression_RendersCorrectly()
+ {
+ var writer = new DesignTimeNodeWriter();
+ var content = "<input checked=\"hello-world @if(@true){ @false }\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpCodeAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateDesignTime(source: sourceDocument);
+
+ // Act
+ writer.WriteCSharpCodeAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ if(@true){
+
+#line default
+#line hidden
+Render Children
+#line 1 ""test.cshtml""
+ }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
+ {
+ var projectEngine = RazorProjectEngine.Create();
+
+ return Lower(codeDocument, projectEngine);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
+ {
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorIntermediateNodeLoweringPhase)
+ {
+ break;
+ }
+ }
+
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(documentNode);
+
+ return documentNode;
+ }
+
+ private class MyExtensionIntermediateNode : ExtensionIntermediateNode
+ {
+ public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ visitor.VisitDefault(this);
+ }
+
+ public override void WriteNode(CodeTarget target, CodeRenderingContext context)
+ {
+ context.CodeWriter.WriteLine("MyExtensionNode");
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/LiteralRuntimeNodeWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/LiteralRuntimeNodeWriterTest.cs
new file mode 100644
index 0000000000..be55c8e1a8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/LiteralRuntimeNodeWriterTest.cs
@@ -0,0 +1,45 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class LiteralRuntimeNodeWriterTest
+ {
+ [Fact]
+ public void WriteCSharpExpression_UsesWriteLiteral_WritesLinePragma_WithSource()
+ {
+ // Arrange
+ var writer = new LiteralRuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpExpressionIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
+ };
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+WriteLiteral(i++);
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeNodeWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeNodeWriterTest.cs
new file mode 100644
index 0000000000..443acf376f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeNodeWriterTest.cs
@@ -0,0 +1,599 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class RuntimeNodeWriterTest
+ {
+ [Fact]
+ public void WriteUsingDirective_NoSource_WritesContent()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new UsingDirectiveIntermediateNode()
+ {
+ Content = "System",
+ };
+
+ // Act
+ writer.WriteUsingDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"using System;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteUsingDirective_WithSource_WritesContentWithLinePragma()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new UsingDirectiveIntermediateNode()
+ {
+ Content = "System",
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
+ };
+
+ // Act
+ writer.WriteUsingDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+using System;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_SkipsLinePragma_WithoutSource()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter()
+ {
+ WriteCSharpExpressionMethod = "Test",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpExpressionIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Test(i++);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WritesLinePragma_WithSource()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter()
+ {
+ WriteCSharpExpressionMethod = "Test",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpExpressionIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 3),
+ };
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+Test(i++);
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WithExtensionNode_WritesPadding()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter()
+ {
+ WriteCSharpExpressionMethod = "Test",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpExpressionIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i",
+ Kind = TokenKind.CSharp,
+ });
+ builder.Add(new MyExtensionIntermediateNode());
+ builder.Add(new IntermediateToken()
+ {
+ Content = "++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Test(iRender Children
+++);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpression_WithSource_WritesPadding()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter()
+ {
+ WriteCSharpExpressionMethod = "Test",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpExpressionIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 8, 0, 8, 3),
+ };
+ var builder = IntermediateNodeBuilder.Create(node);
+ builder.Add(new IntermediateToken()
+ {
+ Content = "i",
+ Kind = TokenKind.CSharp,
+ });
+ builder.Add(new MyExtensionIntermediateNode());
+ builder.Add(new IntermediateToken()
+ {
+ Content = "++",
+ Kind = TokenKind.CSharp,
+ });
+
+ // Act
+ writer.WriteCSharpExpression(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ Test(iRender Children
+++);
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WhitespaceContent_DoesNothing()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpCodeIntermediateNode();
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = " \t"
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Empty(csharp);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_SkipsLinePragma_WithoutSource()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpCodeIntermediateNode();
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = "if (true) { }"
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"if (true) { }
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WritesLinePragma_WithSource()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpCodeIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 13),
+ };
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = "if (true) { }",
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+if (true) { }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCode_WritesPadding_WithSource()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new CSharpCodeIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 17),
+ };
+ IntermediateNodeBuilder.Create(node)
+ .Add(new IntermediateToken()
+ {
+ Kind = TokenKind.CSharp,
+ Content = " if (true) { }",
+ });
+
+ // Act
+ writer.WriteCSharpCode(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+ if (true) { }
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteHtmlContent_RendersContentCorrectly()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new HtmlContentIntermediateNode();
+ node.Children.Add(new IntermediateToken()
+ {
+ Content = "SomeContent",
+ Kind = TokenKind.Html,
+ });
+
+ // Act
+ writer.WriteHtmlContent(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"WriteLiteral(""SomeContent"");
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteHtmlContent_LargeStringLiteral_UsesMultipleWrites()
+ {
+ // Arrange
+ var codeWriter = new CodeWriter();
+ var writer = new RuntimeNodeWriter();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new HtmlContentIntermediateNode();
+ node.Children.Add(new IntermediateToken()
+ {
+ Content = new string('*', 2000),
+ Kind = TokenKind.Html,
+ });
+
+ // Act
+ writer.WriteHtmlContent(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(string.Format(
+@"WriteLiteral(@""{0}"");
+WriteLiteral(@""{1}"");
+", new string('*', 1024), new string('*', 976)),
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteHtmlAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter();
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single();
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.WriteHtmlAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"BeginWriteAttribute(""checked"", "" checked=\"""", 6, ""\"""", 34, 2);
+Render Children
+Render Children
+EndWriteAttribute();
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteHtmlAttributeValue_RendersCorrectly()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter();
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[0] as HtmlAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.WriteHtmlAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"WriteAttributeValue("""", 16, ""hello-world"", 16, 11, true);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpressionAttributeValue_RendersCorrectly()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter();
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpExpressionAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.WriteCSharpExpressionAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+WriteAttributeValue("" "", 27, false, 28, 6, false);
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCodeAttributeValue_BuffersResult()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter();
+
+ var content = "<input checked=\"hello-world @if(@true){ }\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpCodeAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime(source: sourceDocument);
+
+ // Act
+ writer.WriteCSharpCodeAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"WriteAttributeValue("" "", 27, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 1 ""test.cshtml""
+ if(@true){ }
+
+#line default
+#line hidden
+ PopWriter();
+}
+), 28, 13, false);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void BeginWriterScope_UsesSpecifiedWriter_RendersCorrectly()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter()
+ {
+ PushWriterMethod = "TestPushWriter"
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.BeginWriterScope(context, "MyWriter");
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"TestPushWriter(MyWriter);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void EndWriterScope_RendersCorrectly()
+ {
+ // Arrange
+ var writer = new RuntimeNodeWriter()
+ {
+ PopWriterMethod = "TestPopWriter"
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.EndWriterScope(context);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"TestPopWriter();
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
+ {
+ var projectEngine = RazorProjectEngine.Create();
+
+ return Lower(codeDocument, projectEngine);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
+ {
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorIntermediateNodeLoweringPhase)
+ {
+ break;
+ }
+ }
+
+ var irDocument = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(irDocument);
+
+ return irDocument;
+ }
+
+ private class MyExtensionIntermediateNode : ExtensionIntermediateNode
+ {
+ public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ visitor.VisitDefault(this);
+ }
+
+ public override void WriteNode(CodeTarget target, CodeRenderingContext context)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriterTest.cs
new file mode 100644
index 0000000000..87d2d59c2e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/TagHelperHtmlAttributeRuntimeNodeWriterTest.cs
@@ -0,0 +1,125 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
+{
+ public class TagHelperHtmlAttributeRuntimeNodeWriterTest
+ {
+ [Fact]
+ public void WriteHtmlAttributeValue_RendersCorrectly()
+ {
+ var writer = new TagHelperHtmlAttributeRuntimeNodeWriter();
+
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[0] as HtmlAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.WriteHtmlAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"AddHtmlAttributeValue("""", 16, ""hello-world"", 16, 11, true);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpExpressionAttributeValue_RendersCorrectly()
+ {
+ var writer = new TagHelperHtmlAttributeRuntimeNodeWriter();
+ var content = "<input checked=\"hello-world @false\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpExpressionAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ writer.WriteCSharpExpressionAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 1 ""test.cshtml""
+AddHtmlAttributeValue("" "", 27, false, 28, 6, false);
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteCSharpCodeAttributeValue_BuffersResult()
+ {
+ var writer = new TagHelperHtmlAttributeRuntimeNodeWriter();
+
+ var content = "<input checked=\"hello-world @if(@true){ }\" />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var documentNode = Lower(codeDocument);
+ var node = documentNode.Children.OfType<HtmlAttributeIntermediateNode>().Single().Children[1] as CSharpCodeAttributeValueIntermediateNode;
+
+ var context = TestCodeRenderingContext.CreateRuntime(source: sourceDocument);
+
+ // Act
+ writer.WriteCSharpCodeAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"AddHtmlAttributeValue("" "", 27, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 1 ""test.cshtml""
+ if(@true){ }
+
+#line default
+#line hidden
+ PopWriter();
+}
+), 28, 13, false);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
+ {
+ var projectEngine = RazorProjectEngine.Create();
+
+ return Lower(codeDocument, projectEngine);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
+ {
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorIntermediateNodeLoweringPhase)
+ {
+ break;
+ }
+ }
+
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(documentNode);
+
+ return documentNode;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs
new file mode 100644
index 0000000000..2a6b2a8198
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultAllowedChildTagDescriptorBuilderTest.cs
@@ -0,0 +1,24 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultAllowedChildTagDescriptorBuilderTest
+ {
+ [Fact]
+ public void Build_DisplayNameIsName()
+ {
+ // Arrange
+ var builder = new DefaultAllowedChildTagDescriptorBuilder(null);
+ builder.Name = "foo";
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal("foo", descriptor.DisplayName);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultBoundAttributeDescriptorBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultBoundAttributeDescriptorBuilderTest.cs
new file mode 100644
index 0000000000..52317aa157
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultBoundAttributeDescriptorBuilderTest.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultBoundAttributeDescriptorBuilderTest
+ {
+ [Fact]
+ public void DisplayName_SetsDescriptorsDisplayName()
+ {
+ // Arrange
+ var expectedDisplayName = "ExpectedDisplayName";
+
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder.DisplayName(expectedDisplayName);
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal(expectedDisplayName, descriptor.DisplayName);
+ }
+
+ [Fact]
+ public void DisplayName_DefaultsToPropertyLookingDisplayName()
+ {
+ // Arrange
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
+ tagHelperBuilder.TypeName("TestTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .TypeName(typeof(int).FullName)
+ .PropertyName("SomeProperty");
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal("int TestTagHelper.SomeProperty", descriptor.DisplayName);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultDocumentClassifierPassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultDocumentClassifierPassTest.cs
new file mode 100644
index 0000000000..2d47373f3c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultDocumentClassifierPassTest.cs
@@ -0,0 +1,60 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ // We're purposely lean on tests here because the functionality is well covered by
+ // integration tests, and is mostly implemented by the base class.
+ public class DefaultDocumentClassifierPassTest
+ {
+ [Fact]
+ public void Execute_IgnoresDocumentsWithDocumentKind()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ DocumentKind = "ignore",
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var pass = new DefaultDocumentClassifierPass();
+ pass.Engine = RazorProjectEngine.Create().Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Equal("ignore", documentNode.DocumentKind);
+ NoChildren(documentNode);
+ }
+
+ [Fact]
+ public void Execute_CreatesClassStructure()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var pass = new DefaultDocumentClassifierPass();
+ pass.Engine = RazorProjectEngine.Create().Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Equal("default", documentNode.DocumentKind);
+
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ NoChildren(method);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultItemCollectionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultItemCollectionTest.cs
new file mode 100644
index 0000000000..aee4d07fe0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultItemCollectionTest.cs
@@ -0,0 +1,54 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class ItemCollectionTest
+ {
+ [Fact]
+ public void Get_MissingValueReturnsNull()
+ {
+ // Arrange
+ var items = new ItemCollection();
+
+ // Act
+ var value = items["foo"];
+
+ // Assert
+ Assert.Null(value);
+ }
+
+ [Fact]
+ public void GetAndSet_ReturnsValue()
+ {
+ // Arrange
+ var items = new ItemCollection();
+
+ var expected = "bar";
+ items["foo"] = expected;
+
+ // Act
+ var value = items["foo"];
+
+ // Assert
+ Assert.Same(expected, value);
+ }
+
+ [Fact]
+ public void Set_CanSetValueToNull()
+ {
+ // Arrange
+ var items = new ItemCollection();
+
+ items["foo"] = "bar";
+
+ // Act
+ items["foo"] = null;
+
+ // Assert
+ Assert.Null(items["foo"]);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCSharpLoweringPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCSharpLoweringPhaseTest.cs
new file mode 100644
index 0000000000..e76c97557f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCSharpLoweringPhaseTest.cs
@@ -0,0 +1,87 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorCSharpLoweringPhaseTest
+ {
+ [Fact]
+ public void Execute_ThrowsForMissingDependency_IRDocument()
+ {
+ // Arrange
+ var phase = new DefaultRazorCSharpLoweringPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source));
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorCSharpLoweringPhase)}' phase requires a '{nameof(DocumentIntermediateNode)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency_CodeTarget()
+ {
+ // Arrange
+ var phase = new DefaultRazorCSharpLoweringPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source));
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ };
+ codeDocument.SetDocumentIntermediateNode(irDocument);
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The document of kind 'test' does not have a '{nameof(CodeTarget)}'. " +
+ $"The document classifier must set a value for '{nameof(DocumentIntermediateNode.Target)}'.");
+ }
+
+ [Fact]
+ public void Execute_CollatesIRDocumentDiagnosticsFromSourceDocument()
+ {
+ // Arrange
+ var phase = new DefaultRazorCSharpLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+ var codeDocument = TestRazorCodeDocument.Create("<p class=@(");
+ var options = RazorCodeGenerationOptions.CreateDefault();
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Target = CodeTarget.CreateDefault(codeDocument, options),
+ Options = options,
+ };
+ var expectedDiagnostic = RazorDiagnostic.Create(
+ new RazorDiagnosticDescriptor("1234", () => "I am an error.", RazorDiagnosticSeverity.Error),
+ new SourceSpan("SomeFile.cshtml", 11, 0, 11, 1));
+ irDocument.Diagnostics.Add(expectedDiagnostic);
+ codeDocument.SetDocumentIntermediateNode(irDocument);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var csharpDocument = codeDocument.GetCSharpDocument();
+ var diagnostic = Assert.Single(csharpDocument.Diagnostics);
+ Assert.Same(expectedDiagnostic, diagnostic);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCodeDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCodeDocumentTest.cs
new file mode 100644
index 0000000000..415dcadb3b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorCodeDocumentTest.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorCodeDocumentTest
+ {
+ [Fact]
+ public void Ctor()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+
+ var imports = new RazorSourceDocument[]
+ {
+ TestRazorSourceDocument.Create(),
+ };
+
+ // Act
+ var code = new DefaultRazorCodeDocument(source, imports);
+
+ // Assert
+ Assert.Same(source, code.Source);
+ Assert.NotNull(code.Items);
+
+ Assert.NotSame(imports, code.Imports);
+ Assert.Collection(imports, d => Assert.Same(imports[0], d));
+ }
+
+ [Fact]
+ public void Ctor_AllowsNullForImports()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+
+ // Act
+ var code = new DefaultRazorCodeDocument(source, imports: null);
+
+ // Assert
+ Assert.Same(source, code.Source);
+ Assert.NotNull(code.Items);
+ Assert.Empty(code.Imports);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDiagnosticTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDiagnosticTest.cs
new file mode 100644
index 0000000000..bf8f3099ce
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDiagnosticTest.cs
@@ -0,0 +1,217 @@
+// Copyright(c) .NET Foundation.All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Globalization;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorDiagnosticTest
+ {
+ [Fact]
+ public void DefaultRazorDiagnostic_Ctor()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "error", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ // Act
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+
+ // Assert
+ Assert.Equal("RZ0000", diagnostic.Id);
+ Assert.Equal(RazorDiagnosticSeverity.Error, diagnostic.Severity);
+ Assert.Equal(span, diagnostic.Span);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_GetMessage()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "error", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+
+ // Act
+ var result = diagnostic.GetMessage();
+
+ // Assert
+ Assert.Equal("error", result);
+ }
+
+
+ [Fact]
+ public void DefaultRazorDiagnostic_GetMessage_WithArgs()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new[] { "error" });
+
+ // Act
+ var result = diagnostic.GetMessage();
+
+ // Assert
+ Assert.Equal("this is an error", result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_GetMessage_WithArgs_FormatProvider()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new object[] { 1.3m });
+
+ // Act
+ var result = diagnostic.GetMessage(new CultureInfo("fr-FR"));
+
+ // Assert
+ Assert.Equal("this is an 1,3", result);
+ }
+
+
+ [Fact]
+ public void DefaultRazorDiagnostic_ToString()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an error", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+
+ // Act
+ var result = diagnostic.ToString();
+
+ // Assert
+ Assert.Equal("test.cs(2,9): Error RZ0000: this is an error", result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_ToString_FormatProvider()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic = new DefaultRazorDiagnostic(descriptor, span, new object[] { 1.3m });
+
+ // Act
+ var result = ((IFormattable)diagnostic).ToString("ignored", new CultureInfo("fr-FR"));
+
+ // Assert
+ Assert.Equal("test.cs(2,9): Error RZ0000: this is an 1,3", result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_Equals()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+
+ // Act
+ var result = diagnostic1.Equals(diagnostic2);
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_NotEquals_DifferentLocation()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span1 = new SourceSpan("test.cs", 15, 1, 8, 5);
+ var span2 = new SourceSpan("test.cs", 15, 1, 8, 3);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor, span1, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor, span2, new object[0]);
+
+ // Act
+ var result = diagnostic1.Equals(diagnostic2);
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_NotEquals_DifferentId()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0002", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor1, span, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor2, span, new object[0]);
+
+ // Act
+ var result = diagnostic1.Equals(diagnostic2);
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_HashCodesEqual()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor, span, new object[0]);
+
+ // Act
+ var result = diagnostic1.GetHashCode() == diagnostic2.GetHashCode();
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_HashCodesNotEqual_DifferentLocation()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0000", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span1 = new SourceSpan("test.cs", 15, 1, 8, 5);
+ var span2 = new SourceSpan("test.cs", 15, 1, 8, 3);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor, span1, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor, span2, new object[0]);
+
+ // Act
+ var result = diagnostic1.GetHashCode() == diagnostic2.GetHashCode();
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void DefaultRazorDiagnostic_HashCodesNotEqual_DifferentId()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0002", () => "this is an {0}", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ var diagnostic1 = new DefaultRazorDiagnostic(descriptor1, span, new object[0]);
+ var diagnostic2 = new DefaultRazorDiagnostic(descriptor2, span, new object[0]);
+
+ // Act
+ var result = diagnostic1.GetHashCode() == diagnostic2.GetHashCode();
+
+ // Assert
+ Assert.False(result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDirectiveClassifierPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDirectiveClassifierPhaseTest.cs
new file mode 100644
index 0000000000..306be8c445
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDirectiveClassifierPhaseTest.cs
@@ -0,0 +1,102 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Testing;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorDirectiveClassifierPhaseTest
+ {
+ [Fact]
+ public void OnInitialized_OrdersPassesInAscendingOrder()
+ {
+ // Arrange & Act
+ var phase = new DefaultRazorDirectiveClassifierPhase();
+
+ var first = Mock.Of<IRazorDirectiveClassifierPass>(p => p.Order == 15);
+ var second = Mock.Of<IRazorDirectiveClassifierPass>(p => p.Order == 17);
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(second);
+ b.Features.Add(first);
+ });
+
+ // Assert
+ Assert.Collection(
+ phase.Passes,
+ p => Assert.Same(first, p),
+ p => Assert.Same(second, p));
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency()
+ {
+ // Arrange
+ var phase = new DefaultRazorDirectiveClassifierPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorDirectiveClassifierPhase)}' phase requires a '{nameof(DocumentIntermediateNode)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_ExecutesPhasesInOrder()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // We're going to set up mocks to simulate a sequence of passes. We don't care about
+ // what's in the nodes, we're just going to look at the identity via strict mocks.
+ var originalNode = new DocumentIntermediateNode();
+ var firstPassNode = new DocumentIntermediateNode();
+ var secondPassNode = new DocumentIntermediateNode();
+ codeDocument.SetDocumentIntermediateNode(originalNode);
+
+ var firstPass = new Mock<IRazorDirectiveClassifierPass>(MockBehavior.Strict);
+ firstPass.SetupGet(m => m.Order).Returns(0);
+ firstPass.SetupProperty(m => m.Engine);
+ firstPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ originalNode.Children.Add(firstPassNode);
+ });
+
+ var secondPass = new Mock<IRazorDirectiveClassifierPass>(MockBehavior.Strict);
+ secondPass.SetupGet(m => m.Order).Returns(1);
+ secondPass.SetupProperty(m => m.Engine);
+ secondPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ // Works only when the first pass has run before this.
+ originalNode.Children[0].Children.Add(secondPassNode);
+ });
+
+ var phase = new DefaultRazorDirectiveClassifierPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(firstPass.Object);
+ b.Features.Add(secondPass.Object);
+ });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.Same(secondPassNode, codeDocument.GetDocumentIntermediateNode().Children[0].Children[0]);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDocumentClassifierPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDocumentClassifierPhaseTest.cs
new file mode 100644
index 0000000000..0f384b851e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorDocumentClassifierPhaseTest.cs
@@ -0,0 +1,102 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Testing;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorDocumentClassifierPhaseTest
+ {
+ [Fact]
+ public void OnInitialized_OrdersPassesInAscendingOrder()
+ {
+ // Arrange & Act
+ var phase = new DefaultRazorDocumentClassifierPhase();
+
+ var first = Mock.Of<IRazorDocumentClassifierPass>(p => p.Order == 15);
+ var second = Mock.Of<IRazorDocumentClassifierPass>(p => p.Order == 17);
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(second);
+ b.Features.Add(first);
+ });
+
+ // Assert
+ Assert.Collection(
+ phase.Passes,
+ p => Assert.Same(first, p),
+ p => Assert.Same(second, p));
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency()
+ {
+ // Arrange
+ var phase = new DefaultRazorDocumentClassifierPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorDocumentClassifierPhase)}' phase requires a '{nameof(DocumentIntermediateNode)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_ExecutesPhasesInOrder()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // We're going to set up mocks to simulate a sequence of passes. We don't care about
+ // what's in the nodes, we're just going to look at the identity via strict mocks.
+ var originalNode = new DocumentIntermediateNode();
+ var firstPassNode = new DocumentIntermediateNode();
+ var secondPassNode = new DocumentIntermediateNode();
+ codeDocument.SetDocumentIntermediateNode(originalNode);
+
+ var firstPass = new Mock<IRazorDocumentClassifierPass>(MockBehavior.Strict);
+ firstPass.SetupGet(m => m.Order).Returns(0);
+ firstPass.SetupProperty(m => m.Engine);
+ firstPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ originalNode.Children.Add(firstPassNode);
+ });
+
+ var secondPass = new Mock<IRazorDocumentClassifierPass>(MockBehavior.Strict);
+ secondPass.SetupGet(m => m.Order).Returns(1);
+ secondPass.SetupProperty(m => m.Engine);
+ secondPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ // Works only when the first pass has run before this.
+ originalNode.Children[0].Children.Add(secondPassNode);
+ });
+
+ var phase = new DefaultRazorDocumentClassifierPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(firstPass.Object);
+ b.Features.Add(secondPass.Object);
+ });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.Same(secondPassNode, codeDocument.GetDocumentIntermediateNode().Children[0].Children[0]);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineBuilderTest.cs
new file mode 100644
index 0000000000..a1c804287a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineBuilderTest.cs
@@ -0,0 +1,42 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorEngineBuilderTest
+ {
+ [Fact]
+ public void Build_AddsFeaturesAndPhases()
+ {
+ // Arrange
+ var builder = new DefaultRazorEngineBuilder(designTime: false);
+
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+
+ var features = builder.Features.ToArray();
+ var phases = builder.Phases.ToArray();
+
+ // Act
+ var engine = builder.Build();
+
+ // Assert
+ Assert.Collection(
+ engine.Features,
+ f => Assert.Same(features[0], f),
+ f => Assert.Same(features[1], f));
+
+ Assert.Collection(
+ engine.Phases,
+ p => Assert.Same(phases[0], p),
+ p => Assert.Same(phases[1], p));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineTest.cs
new file mode 100644
index 0000000000..15b3122969
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorEngineTest.cs
@@ -0,0 +1,72 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorEngineTest
+ {
+ [Fact]
+ public void Ctor_InitializesPhasesAndFeatures()
+ {
+ // Arrange
+ var features = new IRazorEngineFeature[]
+ {
+ Mock.Of<IRazorEngineFeature>(),
+ Mock.Of<IRazorEngineFeature>(),
+ };
+
+ var phases = new IRazorEnginePhase[]
+ {
+ Mock.Of<IRazorEnginePhase>(),
+ Mock.Of<IRazorEnginePhase>(),
+ };
+
+ // Act
+ var engine = new DefaultRazorEngine(features, phases);
+
+ // Assert
+ for (var i = 0; i < features.Length; i++)
+ {
+ Assert.Same(engine, features[i].Engine);
+ }
+
+ for (var i = 0; i < phases.Length; i++)
+ {
+ Assert.Same(engine, phases[i].Engine);
+ }
+ }
+
+ [Fact]
+ public void Process_CallsAllPhases()
+ {
+ // Arrange
+ var features = new IRazorEngineFeature[]
+ {
+ Mock.Of<IRazorEngineFeature>(),
+ Mock.Of<IRazorEngineFeature>(),
+ };
+
+ var phases = new IRazorEnginePhase[]
+ {
+ Mock.Of<IRazorEnginePhase>(),
+ Mock.Of<IRazorEnginePhase>(),
+ };
+
+ var engine = new DefaultRazorEngine(features, phases);
+ var document = TestRazorCodeDocument.CreateEmpty();
+
+ // Act
+ engine.Process(document);
+
+ // Assert
+ for (var i = 0; i < phases.Length; i++)
+ {
+ var mock = Mock.Get(phases[i]);
+ mock.Verify(p => p.Execute(document), Times.Once());
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs
new file mode 100644
index 0000000000..c841c569a6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest.cs
@@ -0,0 +1,519 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+using Moq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorIntermediateNodeLoweringPhaseIntegrationTest
+ {
+ [Fact]
+ public void Lower_SetsOptions_Defaults()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Assert.NotNull(documentNode.Options);
+ Assert.False(documentNode.Options.DesignTime);
+ Assert.Equal(4, documentNode.Options.IndentSize);
+ Assert.False(documentNode.Options.IndentWithTabs);
+ }
+
+ [Fact]
+ public void Lower_SetsOptions_RunsConfigureCallbacks()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var callback = new Mock<IConfigureRazorCodeGenerationOptionsFeature>();
+ callback
+ .Setup(c => c.Configure(It.IsAny<RazorCodeGenerationOptionsBuilder>()))
+ .Callback<RazorCodeGenerationOptionsBuilder>(o =>
+ {
+ o.IndentSize = 17;
+ o.IndentWithTabs = true;
+ o.SuppressChecksum = true;
+ });
+
+ // Act
+ var documentNode = Lower(
+ codeDocument,
+ builder: b =>
+ {
+ b.Features.Add(callback.Object);
+ },
+ designTime: true);
+
+ // Assert
+ Assert.NotNull(documentNode.Options);
+ Assert.True(documentNode.Options.DesignTime);
+ Assert.Equal(17, documentNode.Options.IndentSize);
+ Assert.True(documentNode.Options.IndentWithTabs);
+ Assert.True(documentNode.Options.SuppressChecksum);
+ }
+
+ [Fact]
+ public void Lower_HelloWorld()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create("Hello, World!");
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(documentNode,
+ n => Html("Hello, World!", n));
+ }
+
+ [Fact]
+ public void Lower_HtmlWithDataDashAttributes()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"
+<html>
+ <body>
+ <span data-val=""@Hello"" />
+ </body>
+</html>");
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(documentNode,
+ n => Html(
+@"
+<html>
+ <body>
+ <span data-val=""", n),
+ n => CSharpExpression("Hello", n),
+ n => Html(@""" />
+ </body>
+</html>", n));
+ }
+
+ [Fact]
+ public void Lower_HtmlWithConditionalAttributes()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"
+<html>
+ <body>
+ <span val=""@Hello World"" />
+ </body>
+</html>");
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(documentNode,
+ n => Html(
+@"
+<html>
+ <body>
+ <span", n),
+
+ n => ConditionalAttribute(
+ prefix: " val=\"",
+ name: "val",
+ suffix: "\"",
+ node: n,
+ valueValidators: new Action<IntermediateNode>[]
+ {
+ value => CSharpExpressionAttributeValue(string.Empty, "Hello", value),
+ value => LiteralAttributeValue(" ", "World", value)
+ }),
+ n => Html(@" />
+ </body>
+</html>", n));
+ }
+
+ [Fact]
+ public void Lower_WithFunctions()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@functions { public int Foo { get; set; }}");
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(documentNode,
+ n => Directive(
+ "functions",
+ n,
+ c => Assert.IsType<CSharpCodeIntermediateNode>(c)));
+ }
+
+ [Fact]
+ public void Lower_WithUsing()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@using System");
+ var expectedSourceLocation = new SourceSpan(codeDocument.Source.FilePath, 1, 0, 1, 12);
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(documentNode,
+ n =>
+ {
+ Using("System", n);
+ Assert.Equal(expectedSourceLocation, n.Source);
+ });
+ }
+
+ [Fact]
+ public void Lower_TagHelpers()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@addTagHelper *, TestAssembly
+<span val=""@Hello World""></span>");
+ var tagHelpers = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "span",
+ typeName: "SpanTagHelper",
+ assemblyName: "TestAssembly")
+ };
+
+ // Act
+ var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
+
+ // Assert
+ Children(documentNode,
+ n => Directive(
+ SyntaxConstants.CSharp.AddTagHelperKeyword,
+ n,
+ v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
+ n => TagHelper(
+ "span",
+ TagMode.StartTagAndEndTag,
+ tagHelpers,
+ n,
+ c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
+ c => TagHelperHtmlAttribute(
+ "val",
+ AttributeStructure.DoubleQuotes,
+ c,
+ v => CSharpExpressionAttributeValue(string.Empty, "Hello", v),
+ v => LiteralAttributeValue(" ", "World", v))));
+ }
+
+ [Fact]
+ public void Lower_TagHelpers_WithPrefix()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@addTagHelper *, TestAssembly
+@tagHelperPrefix cool:
+<cool:span val=""@Hello World""></cool:span>");
+ var tagHelpers = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "span",
+ typeName: "SpanTagHelper",
+ assemblyName: "TestAssembly")
+ };
+
+ // Act
+ var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
+
+ // Assert
+ Children(documentNode,
+ n => Directive(
+ SyntaxConstants.CSharp.AddTagHelperKeyword,
+ n,
+ v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
+ n => Directive(
+ SyntaxConstants.CSharp.TagHelperPrefixKeyword,
+ n,
+ v => DirectiveToken(DirectiveTokenKind.String, "cool:", v)),
+ n => TagHelper(
+ "span", // Note: this is span not cool:span
+ TagMode.StartTagAndEndTag,
+ tagHelpers,
+ n,
+ c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
+ c => TagHelperHtmlAttribute(
+ "val",
+ AttributeStructure.DoubleQuotes,
+ c,
+ v => CSharpExpressionAttributeValue(string.Empty, "Hello", v),
+ v => LiteralAttributeValue(" ", "World", v))));
+ }
+
+ [Fact]
+ public void Lower_TagHelper_InSection()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@addTagHelper *, TestAssembly
+@section test {
+<span val=""@Hello World""></span>
+}");
+ var tagHelpers = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "span",
+ typeName: "SpanTagHelper",
+ assemblyName: "TestAssembly")
+ };
+
+ // Act
+ var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
+
+ // Assert
+ Children(
+ documentNode,
+ n => Directive(
+ SyntaxConstants.CSharp.AddTagHelperKeyword,
+ n,
+ v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
+ n => Directive(
+ "section",
+ n,
+ c1 => DirectiveToken(DirectiveTokenKind.Member, "test", c1),
+ c1 => Html(Environment.NewLine, c1),
+ c1 => TagHelper(
+ "span",
+ TagMode.StartTagAndEndTag,
+ tagHelpers,
+ c1,
+ c2 => Assert.IsType<TagHelperBodyIntermediateNode>(c2),
+ c2 => TagHelperHtmlAttribute(
+ "val",
+ AttributeStructure.DoubleQuotes,
+ c2,
+ v => CSharpExpressionAttributeValue(string.Empty, "Hello", v),
+ v => LiteralAttributeValue(" ", "World", v))),
+ c1 => Html(Environment.NewLine, c1)));
+ }
+
+ [Fact]
+ public void Lower_TagHelpersWithBoundAttribute()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.Create(@"@addTagHelper *, TestAssembly
+<input bound='foo' />");
+ var tagHelpers = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("FooProp")
+ .TypeName("System.String"),
+ })
+ };
+
+ // Act
+ var documentNode = Lower(codeDocument, tagHelpers: tagHelpers);
+
+ // Assert
+ Children(
+ documentNode,
+ n => Directive(
+ SyntaxConstants.CSharp.AddTagHelperKeyword,
+ n,
+ v => DirectiveToken(DirectiveTokenKind.String, "*, TestAssembly", v)),
+ n => TagHelper(
+ "input",
+ TagMode.SelfClosing,
+ tagHelpers,
+ n,
+ c => Assert.IsType<TagHelperBodyIntermediateNode>(c),
+ c => SetTagHelperProperty(
+ "bound",
+ "FooProp",
+ AttributeStructure.SingleQuotes,
+ c,
+ v => Html("foo", v))));
+ }
+
+ [Fact]
+ public void Lower_WithImports_Using()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create(@"@using System.Threading.Tasks
+<p>Hi!</p>");
+ var imports = new[]
+ {
+ TestRazorSourceDocument.Create("@using System.Globalization"),
+ TestRazorSourceDocument.Create("@using System.Text"),
+ };
+
+ var codeDocument = TestRazorCodeDocument.Create(source, imports);
+
+ // Act
+ var documentNode = Lower(codeDocument);
+
+ // Assert
+ Children(
+ documentNode,
+ n => Using("System.Globalization", n),
+ n => Using("System.Text", n),
+ n => Using("System.Threading.Tasks", n),
+ n => Html("<p>Hi!</p>", n));
+ }
+
+ [Fact]
+ public void Lower_WithMultipleImports_SingleLineFileScopedSinglyOccurring()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create("<p>Hi!</p>");
+ var imports = new[]
+ {
+ TestRazorSourceDocument.Create("@test value1"),
+ TestRazorSourceDocument.Create("@test value2"),
+ };
+
+ var codeDocument = TestRazorCodeDocument.Create(source, imports);
+
+ // Act
+ var documentNode = Lower(codeDocument, b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective(
+ "test",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.AddMemberToken();
+ builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
+ }));
+ });
+
+ // Assert
+ Children(
+ documentNode,
+ n => Directive("test", n, c => DirectiveToken(DirectiveTokenKind.Member, "value2", c)),
+ n => Html("<p>Hi!</p>", n));
+ }
+
+ [Fact]
+ public void Lower_WithImports_IgnoresBlockDirective()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create("<p>Hi!</p>");
+ var imports = new[]
+ {
+ TestRazorSourceDocument.Create("@block token { }"),
+ };
+
+ var codeDocument = TestRazorCodeDocument.Create(source, imports);
+
+ // Act
+ var documentNode = Lower(codeDocument, b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective("block", DirectiveKind.RazorBlock, d => d.AddMemberToken()));
+ });
+
+ // Assert
+ Children(
+ documentNode,
+ n => Html("<p>Hi!</p>", n));
+ }
+
+ private DocumentIntermediateNode Lower(
+ RazorCodeDocument codeDocument,
+ Action<RazorProjectEngineBuilder> builder = null,
+ IEnumerable<TagHelperDescriptor> tagHelpers = null,
+ bool designTime = false)
+ {
+ tagHelpers = tagHelpers ?? new TagHelperDescriptor[0];
+
+ Action<RazorProjectEngineBuilder> configureEngine = b =>
+ {
+ builder?.Invoke(b);
+
+ FunctionsDirective.Register(b);
+ SectionDirective.Register(b);
+ b.AddTagHelpers(tagHelpers);
+
+ b.Features.Add(new DesignTimeOptionsFeature(designTime));
+ };
+
+ var projectEngine = RazorProjectEngine.Create(configureEngine);
+
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorIntermediateNodeLoweringPhase)
+ {
+ break;
+ }
+ }
+
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(documentNode);
+
+ return documentNode;
+ }
+
+ private static TagHelperDescriptor CreateTagHelperDescriptor(
+ string tagName,
+ string typeName,
+ string assemblyName,
+ IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
+ {
+ var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
+ builder.TypeName(typeName);
+
+ if (attributes != null)
+ {
+ foreach (var attributeBuilder in attributes)
+ {
+ builder.BoundAttributeDescriptor(attributeBuilder);
+ }
+ }
+
+ builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
+
+ var descriptor = builder.Build();
+
+ return descriptor;
+ }
+
+ private class DesignTimeOptionsFeature : IConfigureRazorParserOptionsFeature, IConfigureRazorCodeGenerationOptionsFeature
+ {
+ private bool _designTime;
+
+ public DesignTimeOptionsFeature(bool designTime)
+ {
+ _designTime = designTime;
+ }
+
+ public int Order { get; }
+
+ public RazorEngine Engine { get; set; }
+
+ public void Configure(RazorParserOptionsBuilder options)
+ {
+ options.SetDesignTime(_designTime);
+ }
+
+ public void Configure(RazorCodeGenerationOptionsBuilder options)
+ {
+ options.SetDesignTime(_designTime);
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs
new file mode 100644
index 0000000000..908983d50a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorIntermediateNodeLoweringPhaseTest.cs
@@ -0,0 +1,298 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorIntermediateNodeLoweringPhaseTest
+ {
+ [Fact]
+ public void Execute_AutomaticallyImportsSingleLineSinglyOccurringDirective()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateSingleLineDirective(
+ "custom",
+ builder =>
+ {
+ builder.AddStringToken();
+ builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
+ });
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(directive);
+ });
+ var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
+ var importSource = TestRazorSourceDocument.Create("@custom \"hello\"", filePath: "import.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var customDirectives = documentNode.FindDirectiveReferences(directive);
+ var customDirective = (DirectiveIntermediateNode)Assert.Single(customDirectives).Node;
+ var stringToken = Assert.Single(customDirective.Tokens);
+ Assert.Equal("\"hello\"", stringToken.Content);
+ }
+
+ [Fact]
+ public void Execute_AutomaticallyOverridesImportedSingleLineSinglyOccurringDirective_MainDocument()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateSingleLineDirective(
+ "custom",
+ builder =>
+ {
+ builder.AddStringToken();
+ builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
+ });
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(directive);
+ });
+ var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
+ var importSource = TestRazorSourceDocument.Create("@custom \"hello\"", filePath: "import.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("@custom \"world\"");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var customDirectives = documentNode.FindDirectiveReferences(directive);
+ var customDirective = (DirectiveIntermediateNode)Assert.Single(customDirectives).Node;
+ var stringToken = Assert.Single(customDirective.Tokens);
+ Assert.Equal("\"world\"", stringToken.Content);
+ }
+
+ [Fact]
+ public void Execute_AutomaticallyOverridesImportedSingleLineSinglyOccurringDirective_MultipleImports()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateSingleLineDirective(
+ "custom",
+ builder =>
+ {
+ builder.AddStringToken();
+ builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
+ });
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(directive);
+ });
+ var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
+ var importSource1 = TestRazorSourceDocument.Create("@custom \"hello\"", filePath: "import1.cshtml");
+ var importSource2 = TestRazorSourceDocument.Create("@custom \"world\"", filePath: "import2.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource1, options), RazorSyntaxTree.Parse(importSource2, options) });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var customDirectives = documentNode.FindDirectiveReferences(directive);
+ var customDirective = (DirectiveIntermediateNode)Assert.Single(customDirectives).Node;
+ var stringToken = Assert.Single(customDirective.Tokens);
+ Assert.Equal("\"world\"", stringToken.Content);
+ }
+
+ [Fact]
+ public void Execute_DoesNotImportNonFileScopedSinglyOccurringDirectives_Block()
+ {
+ // Arrange
+ var codeBlockDirective = DirectiveDescriptor.CreateCodeBlockDirective("code", b => b.AddStringToken());
+ var razorBlockDirective = DirectiveDescriptor.CreateRazorBlockDirective("razor", b => b.AddStringToken());
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(codeBlockDirective);
+ b.AddDirective(razorBlockDirective);
+ });
+ var options = RazorParserOptions.Create(builder =>
+ {
+ builder.Directives.Add(codeBlockDirective);
+ builder.Directives.Add(razorBlockDirective);
+ });
+ var importSource = TestRazorSourceDocument.Create(
+@"@code ""code block"" { }
+@razor ""razor block"" { }",
+ filePath: "testImports.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var directives = documentNode.Children.OfType<DirectiveIntermediateNode>();
+ Assert.Empty(directives);
+ }
+
+ [Fact]
+ public void Execute_ErrorsForCodeBlockFileScopedSinglyOccurringDirectives()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateCodeBlockDirective("custom", b => b.Usage = DirectiveUsage.FileScopedSinglyOccurring);
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(directive);
+ });
+ var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
+ var importSource = TestRazorSourceDocument.Create("@custom { }", filePath: "import.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported("custom");
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var directives = documentNode.Children.OfType<DirectiveIntermediateNode>();
+ Assert.Empty(directives);
+ var diagnostic = Assert.Single(documentNode.GetAllDiagnostics());
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void Execute_ErrorsForRazorBlockFileScopedSinglyOccurringDirectives()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateRazorBlockDirective("custom", b => b.Usage = DirectiveUsage.FileScopedSinglyOccurring);
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ b.AddDirective(directive);
+ });
+ var options = RazorParserOptions.Create(builder => builder.Directives.Add(directive));
+ var importSource = TestRazorSourceDocument.Create("@custom { }", filePath: "import.cshtml");
+ var codeDocument = TestRazorCodeDocument.Create("<p>NonDirective</p>");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source, options));
+ codeDocument.SetImportSyntaxTrees(new[] { RazorSyntaxTree.Parse(importSource, options) });
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateDirective_BlockDirectiveCannotBeImported("custom");
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var directives = documentNode.Children.OfType<DirectiveIntermediateNode>();
+ Assert.Empty(directives);
+ var diagnostic = Assert.Single(documentNode.GetAllDiagnostics());
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency_SyntaxTree()
+ {
+ // Arrange
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorIntermediateNodeLoweringPhase)}' phase requires a '{nameof(RazorSyntaxTree)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_CollatesSyntaxDiagnosticsFromSourceDocument()
+ {
+ // Arrange
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ });
+ var codeDocument = TestRazorCodeDocument.Create("<p class=@(");
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source));
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ var diagnostic = Assert.Single(documentNode.Diagnostics);
+ Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.",
+ diagnostic.GetMessage());
+ }
+
+ [Fact]
+ public void Execute_CollatesSyntaxDiagnosticsFromImportDocuments()
+ {
+ // Arrange
+ var phase = new DefaultRazorIntermediateNodeLoweringPhase();
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+ b.Features.Add(new DefaultRazorCodeGenerationOptionsFeature(designTime: false));
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+ codeDocument.SetSyntaxTree(RazorSyntaxTree.Parse(codeDocument.Source));
+ codeDocument.SetImportSyntaxTrees(new[]
+ {
+ RazorSyntaxTree.Parse(TestRazorSourceDocument.Create("@ ")),
+ RazorSyntaxTree.Parse(TestRazorSourceDocument.Create("<p @(")),
+ });
+ var options = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.Collection(documentNode.Diagnostics,
+ diagnostic =>
+ {
+ Assert.Equal(@"A space or line break was encountered after the ""@"" character. Only valid identifiers, keywords, comments, ""("" and ""{"" are valid at the start of a code block and they must occur immediately following ""@"" with no space in between.",
+ diagnostic.GetMessage());
+ },
+ diagnostic =>
+ {
+ Assert.Equal(@"The explicit expression block is missing a closing "")"" character. Make sure you have a matching "")"" character for all the ""("" characters within this block, and that none of the "")"" characters are being interpreted as markup.",
+ diagnostic.GetMessage());
+ });
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorOptimizationPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorOptimizationPhaseTest.cs
new file mode 100644
index 0000000000..5a1d6eb238
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorOptimizationPhaseTest.cs
@@ -0,0 +1,102 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Testing;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorOptimizationPhaseTest
+ {
+ [Fact]
+ public void OnInitialized_OrdersPassesInAscendingOrder()
+ {
+ // Arrange & Act
+ var phase = new DefaultRazorOptimizationPhase();
+
+ var first = Mock.Of<IRazorOptimizationPass>(p => p.Order == 15);
+ var second = Mock.Of<IRazorOptimizationPass>(p => p.Order == 17);
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(second);
+ b.Features.Add(first);
+ });
+
+ // Assert
+ Assert.Collection(
+ phase.Passes,
+ p => Assert.Same(first, p),
+ p => Assert.Same(second, p));
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency()
+ {
+ // Arrange
+ var phase = new DefaultRazorOptimizationPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorOptimizationPhase)}' phase requires a '{nameof(DocumentIntermediateNode)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_ExecutesPhasesInOrder()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // We're going to set up mocks to simulate a sequence of passes. We don't care about
+ // what's in the nodes, we're just going to look at the identity via strict mocks.
+ var originalNode = new DocumentIntermediateNode();
+ var firstPassNode = new DocumentIntermediateNode();
+ var secondPassNode = new DocumentIntermediateNode();
+ codeDocument.SetDocumentIntermediateNode(originalNode);
+
+ var firstPass = new Mock<IRazorOptimizationPass>(MockBehavior.Strict);
+ firstPass.SetupGet(m => m.Order).Returns(0);
+ firstPass.SetupProperty(m => m.Engine);
+ firstPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ originalNode.Children.Add(firstPassNode);
+ });
+
+ var secondPass = new Mock<IRazorOptimizationPass>(MockBehavior.Strict);
+ secondPass.SetupGet(m => m.Order).Returns(1);
+ secondPass.SetupProperty(m => m.Engine);
+ secondPass.Setup(m => m.Execute(codeDocument, originalNode)).Callback(() =>
+ {
+ // Works only when the first pass has run before this.
+ originalNode.Children[0].Children.Add(secondPassNode);
+ });
+
+ var phase = new DefaultRazorOptimizationPhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(firstPass.Object);
+ b.Features.Add(secondPass.Object);
+ });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.Same(secondPassNode, codeDocument.GetDocumentIntermediateNode().Children[0].Children[0]);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs
new file mode 100644
index 0000000000..ff6eb09966
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorParsingPhaseTest.cs
@@ -0,0 +1,93 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorParsingPhaseTest
+ {
+ [Fact]
+ public void Execute_AddsSyntaxTree()
+ {
+ // Arrange
+ var phase = new DefaultRazorParsingPhase();
+ var engine = RazorProjectEngine.CreateEmpty(builder =>
+ {
+ builder.Phases.Add(phase);
+ builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest));
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.NotNull(codeDocument.GetSyntaxTree());
+ }
+
+ [Fact]
+ public void Execute_UsesConfigureParserFeatures()
+ {
+ // Arrange
+ var phase = new DefaultRazorParsingPhase();
+ var engine = RazorProjectEngine.CreateEmpty((builder) =>
+ {
+ builder.Phases.Add(phase);
+ builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest));
+ builder.Features.Add(new MyParserOptionsFeature());
+ });
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var syntaxTree = codeDocument.GetSyntaxTree();
+ var directive = Assert.Single(syntaxTree.Options.Directives);
+ Assert.Equal("test", directive.Directive);
+ }
+
+ [Fact]
+ public void Execute_ParsesImports()
+ {
+ // Arrange
+ var phase = new DefaultRazorParsingPhase();
+ var engine = RazorProjectEngine.CreateEmpty((builder) =>
+ {
+ builder.Phases.Add(phase);
+ builder.Features.Add(new DefaultRazorParserOptionsFeature(designTime: false, version: RazorLanguageVersion.Latest));
+ builder.Features.Add(new MyParserOptionsFeature());
+ });
+
+ var imports = new[]
+ {
+ TestRazorSourceDocument.Create(),
+ TestRazorSourceDocument.Create(),
+ };
+
+ var codeDocument = TestRazorCodeDocument.Create(TestRazorSourceDocument.Create(), imports);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.Collection(
+ codeDocument.GetImportSyntaxTrees(),
+ t => { Assert.Same(t.Source, imports[0]); Assert.Equal("test", Assert.Single(t.Options.Directives).Directive); },
+ t => { Assert.Same(t.Source, imports[1]); Assert.Equal("test", Assert.Single(t.Options.Directives).Directive); });
+ }
+
+ private class MyParserOptionsFeature : RazorEngineFeatureBase, IConfigureRazorParserOptionsFeature
+ {
+ public int Order { get; }
+
+ public void Configure(RazorParserOptionsBuilder options)
+ {
+ options.Directives.Add(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineBuilderTest.cs
new file mode 100644
index 0000000000..5323ba3ffa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineBuilderTest.cs
@@ -0,0 +1,65 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorProjectEngineBuilderTest
+ {
+ [Fact]
+ public void Build_AddsFeaturesToRazorEngine()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+ builder.Features.Add(Mock.Of<IRazorProjectEngineFeature>());
+
+ var features = builder.Features.ToArray();
+
+ // Act
+ var projectEngine = builder.Build();
+
+ // Assert
+ Assert.Collection(projectEngine.Engine.Features,
+ feature => Assert.Same(features[0], feature),
+ feature => Assert.Same(features[1], feature));
+ }
+
+ [Fact]
+ public void Build_AddsPhasesToRazorEngine()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+
+ var phases = builder.Phases.ToArray();
+
+ // Act
+ var projectEngine = builder.Build();
+
+ // Assert
+ Assert.Collection(projectEngine.Engine.Phases,
+ phase => Assert.Same(phases[0], phase),
+ phase => Assert.Same(phases[1], phase));
+ }
+
+ [Fact]
+ public void Build_CreatesProjectEngineWithFileSystem()
+ {
+ // Arrange
+ var fileSystem = Mock.Of<RazorProjectFileSystem>();
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, fileSystem);
+
+ // Act
+ var projectEngine = builder.Build();
+
+ // Assert
+ Assert.Same(fileSystem, projectEngine.FileSystem);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineIntegrationTest.cs
new file mode 100644
index 0000000000..38b5082b2e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineIntegrationTest.cs
@@ -0,0 +1,95 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorProjectEngineIntegrationTest
+ {
+ [Fact]
+ public void Process_SetsOptions_Runtime()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("Index.cshtml");
+
+ var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty);
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ var parserOptions = codeDocument.GetParserOptions();
+ Assert.False(parserOptions.DesignTime);
+
+ var codeGenerationOptions = codeDocument.GetCodeGenerationOptions();
+ Assert.False(codeGenerationOptions.DesignTime);
+ Assert.False(codeGenerationOptions.SuppressChecksum);
+ Assert.False(codeGenerationOptions.SuppressMetadataAttributes);
+ }
+
+ [Fact]
+ public void ProcessDesignTime_SetsOptions_DesignTime()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("Index.cshtml");
+
+ var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty);
+
+ // Act
+ var codeDocument = projectEngine.ProcessDesignTime(projectItem);
+
+ // Assert
+ var parserOptions = codeDocument.GetParserOptions();
+ Assert.True(parserOptions.DesignTime);
+
+ var codeGenerationOptions = codeDocument.GetCodeGenerationOptions();
+ Assert.True(codeGenerationOptions.DesignTime);
+ Assert.True(codeGenerationOptions.SuppressChecksum);
+ Assert.True(codeGenerationOptions.SuppressMetadataAttributes);
+ }
+
+ [Fact]
+ public void Process_GetsImportsFromFeature()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("Index.cshtml");
+
+ var testImport = Mock.Of<RazorProjectItem>(i => i.Read() == new MemoryStream() && i.FilePath == "testvalue" && i.Exists == true);
+ var importFeature = new Mock<IImportProjectFeature>();
+ importFeature
+ .Setup(feature => feature.GetImports(It.IsAny<RazorProjectItem>()))
+ .Returns(new[] { testImport });
+
+ var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty, builder =>
+ {
+ builder.SetImportFeature(importFeature.Object);
+ });
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ var import = Assert.Single(codeDocument.Imports);
+ Assert.Equal("testvalue", import.FilePath);
+ }
+
+ [Fact]
+ public void Process_GeneratesCodeDocumentWithValidCSharpDocument()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("Index.cshtml");
+ var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, TestRazorProjectFileSystem.Empty);
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ var csharpDocument = codeDocument.GetCSharpDocument();
+ Assert.NotNull(csharpDocument);
+ Assert.Empty(csharpDocument.Diagnostics);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineTest.cs
new file mode 100644
index 0000000000..c70cdab663
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectEngineTest.cs
@@ -0,0 +1,62 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorProjectEngineTest
+ {
+ [Fact]
+ public void GetImportSourceDocuments_DoesNotIncludeNonExistentItems()
+ {
+ // Arrange
+ var existingItem = new TestRazorProjectItem("Index.cshtml");
+ var nonExistentItem = Mock.Of<RazorProjectItem>(item => item.Exists == false);
+ var items = new[] { existingItem, nonExistentItem };
+
+ // Act
+ var sourceDocuments = DefaultRazorProjectEngine.GetImportSourceDocuments(items);
+
+ // Assert
+ var sourceDocument = Assert.Single(sourceDocuments);
+ Assert.Equal(existingItem.FilePath, sourceDocument.FilePath);
+ }
+
+ [Fact]
+ public void GetImportSourceDocuments_UnreadableItem_Throws()
+ {
+ // Arrange
+ var projectItem = new Mock<RazorProjectItem>(MockBehavior.Strict);
+ projectItem.SetupGet(p => p.Exists).Returns(true);
+ projectItem.SetupGet(p => p.PhysicalPath).Returns("path/to/file.cshtml");
+ projectItem.Setup(p => p.Read()).Throws(new IOException("Couldn't read file."));
+ var items = new[] { projectItem.Object };
+
+ // Act & Assert
+ var exception = Assert.Throws<IOException>(() => DefaultRazorProjectEngine.GetImportSourceDocuments(items));
+ Assert.Equal("Couldn't read file.", exception.Message);
+ }
+
+ [Fact]
+ public void GetImportSourceDocuments_WithSuppressExceptions_UnreadableItem_DoesNotThrow()
+ {
+ // Arrange
+ var projectItem = new Mock<RazorProjectItem>(MockBehavior.Strict);
+ projectItem.SetupGet(p => p.Exists).Returns(true);
+ projectItem.SetupGet(p => p.PhysicalPath).Returns("path/to/file.cshtml");
+ projectItem.SetupGet(p => p.FilePath).Returns("path/to/file.cshtml");
+ projectItem.SetupGet(p => p.RelativePhysicalPath).Returns("path/to/file.cshtml");
+ projectItem.Setup(p => p.Read()).Throws(new IOException("Couldn't read file."));
+ var items = new[] { projectItem.Object };
+
+ // Act
+ var sourceDocuments = DefaultRazorProjectEngine.GetImportSourceDocuments(items, suppressExceptions: true);
+
+ // Assert - Does not throw
+ Assert.Empty(sourceDocuments);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectFileSystemTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectFileSystemTest.cs
new file mode 100644
index 0000000000..af48d1e900
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectFileSystemTest.cs
@@ -0,0 +1,263 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using System.Linq;
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorProjectFileSystemTest
+ {
+ private static string TestFolder { get; } = Path.Combine(
+ TestProject.GetProjectDirectory(typeof(DefaultRazorProjectFileSystemTest)),
+ "TestFiles",
+ "DefaultRazorProjectFileSystem");
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ public void NormalizeAndEnsureValidPath_ThrowsIfPathIsNullOrEmpty(string path)
+ {
+ // Arrange
+ var fileSystem = new TestRazorProjectFileSystem("C:/some/test/path/root");
+
+ // Act and Assert
+ ExceptionAssert.ThrowsArgumentNullOrEmptyString(() => fileSystem.NormalizeAndEnsureValidPath(path), "path");
+ }
+
+ [Fact]
+ public void NormalizeAndEnsureValidPath_NormalizesToAbsolutePath()
+ {
+ // Arrange
+ var fileSystem = new TestRazorProjectFileSystem("C:/some/test/path/root");
+
+ // Act
+ var absolutePath = fileSystem.NormalizeAndEnsureValidPath("file.cshtml");
+
+ // Assert
+ Assert.Equal("C:/some/test/path/root/file.cshtml", absolutePath);
+ }
+
+ [Fact]
+ public void NormalizeAndEnsureValidPath_NormalizesToAbsolutePathWithoutForwardSlash()
+ {
+ // Arrange
+ var fileSystem = new TestRazorProjectFileSystem("C:/some/test/path/root");
+
+ // Act
+ var absolutePath = fileSystem.NormalizeAndEnsureValidPath("/file.cshtml");
+
+ // Assert
+ Assert.Equal("C:/some/test/path/root/file.cshtml", absolutePath);
+ }
+
+ [Fact]
+ public void NormalizeAndEnsureValidPath_NormalizesToForwardSlashes()
+ {
+ // Arrange
+ var fileSystem = new TestRazorProjectFileSystem(@"C:\some\test\path\root");
+
+ // Act
+ var absolutePath = fileSystem.NormalizeAndEnsureValidPath(@"something\file.cshtml");
+
+ // Assert
+ Assert.Equal("C:/some/test/path/root/something/file.cshtml", absolutePath);
+ }
+
+ [Fact]
+ public void EnumerateItems_DiscoversAllCshtmlFiles()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var items = fileSystem.EnumerateItems("/");
+
+ // Assert
+ Assert.Collection(
+ items.OrderBy(f => f.FilePath),
+ item =>
+ {
+ Assert.Equal("/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal("_ViewImports.cshtml", item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/Home.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Home.cshtml"), item.PhysicalPath);
+ Assert.Equal("Home.cshtml", item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/Views/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "_ViewImports.cshtml"), item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/Views/About/About.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "About", "About.cshtml"), item.RelativePhysicalPath);
+ },
+ item =>
+ {
+ Assert.Equal("/Views/Home/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "Home", "_ViewImports.cshtml"), item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/Views/Home/Index.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "Index.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "Home", "Index.cshtml"), item.RelativePhysicalPath);
+ });
+ }
+
+ [Fact]
+ public void EnumerateItems_DiscoversAllCshtmlFiles_UnderSpecifiedBasePath()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var items = fileSystem.EnumerateItems("/Views");
+
+ // Assert
+ Assert.Collection(
+ items.OrderBy(f => f.FilePath),
+ item =>
+ {
+ Assert.Equal("/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/Views", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("_ViewImports.cshtml"), item.RelativePhysicalPath);
+ },
+ item =>
+ {
+ Assert.Equal("/About/About.cshtml", item.FilePath);
+ Assert.Equal("/Views", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("About", "About.cshtml"), item.RelativePhysicalPath);
+ },
+ item =>
+ {
+ Assert.Equal("/Home/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/Views", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Home", "_ViewImports.cshtml"), item.RelativePhysicalPath);
+ },
+ item =>
+ {
+ Assert.Equal("/Home/Index.cshtml", item.FilePath);
+ Assert.Equal("/Views", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "Index.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Home", "Index.cshtml"), item.RelativePhysicalPath);
+ });
+ }
+
+ [Fact]
+ public void EnumerateItems_ReturnsEmptySequence_WhenBasePathDoesNotExist()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var items = fileSystem.EnumerateItems("/Does-Not-Exist");
+
+ // Assert
+ Assert.Empty(items);
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_FindsItemsWithMatchingNames()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var items = fileSystem.FindHierarchicalItems("/Views/Home/Index.cshtml", "_ViewImports.cshtml");
+
+ // Assert
+ Assert.Collection(
+ items,
+ item =>
+ {
+ Assert.Equal("/Views/Home/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "Home", "_ViewImports.cshtml"), item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/Views/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "_ViewImports.cshtml"), item.RelativePhysicalPath);
+
+ },
+ item =>
+ {
+ Assert.Equal("/_ViewImports.cshtml", item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "_ViewImports.cshtml"), item.PhysicalPath);
+ Assert.Equal("_ViewImports.cshtml", item.RelativePhysicalPath);
+
+ });
+ }
+
+ [Fact]
+ public void GetItem_ReturnsFileFromDisk()
+ {
+ // Arrange
+ var filePath = "/Views/About/About.cshtml";
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var item = fileSystem.GetItem(filePath);
+
+ // Assert
+ Assert.True(item.Exists);
+ Assert.Equal(filePath, item.FilePath);
+ Assert.Equal("/", item.BasePath);
+ Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath);
+ Assert.Equal(Path.Combine("Views", "About", "About.cshtml"), item.RelativePhysicalPath);
+ }
+
+ [Fact]
+ public void GetItem_ReturnsNotFoundResult()
+ {
+ // Arrange
+ var path = "/NotFound.cshtml";
+ var fileSystem = new DefaultRazorProjectFileSystem(TestFolder);
+
+ // Act
+ var item = fileSystem.GetItem(path);
+
+ // Assert
+ Assert.False(item.Exists);
+ }
+
+ private class TestRazorProjectFileSystem : DefaultRazorProjectFileSystem
+ {
+ public TestRazorProjectFileSystem(string root) : base(root)
+ {
+ }
+
+ public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectItemTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectItemTest.cs
new file mode 100644
index 0000000000..1fa4453bd3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorProjectItemTest.cs
@@ -0,0 +1,61 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorProjectItemTest
+ {
+ private static string TestFolder { get; } = Path.Combine(
+ TestProject.GetProjectDirectory(typeof(DefaultRazorProjectItemTest)),
+ "TestFiles",
+ "DefaultRazorProjectFileSystem");
+
+ [Fact]
+ public void DefaultRazorProjectItem_SetsProperties()
+ {
+ // Arrange
+ var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
+
+ // Act
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileInfo);
+
+ // Assert
+ Assert.Equal("/Home.cshtml", projectItem.FilePath);
+ Assert.Equal("/", projectItem.BasePath);
+ Assert.True(projectItem.Exists);
+ Assert.Equal("Home.cshtml", projectItem.FileName);
+ Assert.Equal(fileInfo.FullName, projectItem.PhysicalPath);
+ Assert.Equal("Home.cshtml", projectItem.RelativePhysicalPath);
+ }
+
+ [Fact]
+ public void Exists_ReturnsFalseWhenFileDoesNotExist()
+ {
+ // Arrange
+ var fileInfo = new FileInfo(Path.Combine(TestFolder, "Views", "FileDoesNotExist.cshtml"));
+
+ // Act
+ var projectItem = new DefaultRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), fileInfo);
+
+ // Assert
+ Assert.False(projectItem.Exists);
+ }
+
+ [Fact]
+ public void Read_ReturnsReadStream()
+ {
+ // Arrange
+ var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml"));
+ var projectItem = new DefaultRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileInfo);
+
+ // Act
+ var stream = projectItem.Read();
+
+ // Assert
+ Assert.Equal("home-content", new StreamReader(stream).ReadToEnd());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorSyntaxTreePhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorSyntaxTreePhaseTest.cs
new file mode 100644
index 0000000000..d6dc0ac75a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorSyntaxTreePhaseTest.cs
@@ -0,0 +1,94 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Testing;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorSyntaxTreePhaseTest
+ {
+ [Fact]
+ public void OnInitialized_OrdersPassesInAscendingOrder()
+ {
+ // Arrange & Act
+ var phase = new DefaultRazorSyntaxTreePhase();
+
+ var first = Mock.Of<IRazorSyntaxTreePass>(p => p.Order == 15);
+ var second = Mock.Of<IRazorSyntaxTreePass>(p => p.Order == 17);
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(second);
+ b.Features.Add(first);
+ });
+
+ // Assert
+ Assert.Collection(
+ phase.Passes,
+ p => Assert.Same(first, p),
+ p => Assert.Same(second, p));
+ }
+
+ [Fact]
+ public void Execute_ThrowsForMissingDependency()
+ {
+ // Arrange
+ var phase = new DefaultRazorSyntaxTreePhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b => b.Phases.Add(phase));
+
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => phase.Execute(codeDocument),
+ $"The '{nameof(DefaultRazorSyntaxTreePhase)}' phase requires a '{nameof(RazorSyntaxTree)}' " +
+ $"provided by the '{nameof(RazorCodeDocument)}'.");
+ }
+
+ [Fact]
+ public void Execute_ExecutesPhasesInOrder()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ // We're going to set up mocks to simulate a sequence of passes. We don't care about
+ // what's in the trees, we're just going to look at the identity via strict mocks.
+ var originalSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source);
+ var firstPassSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source);
+ var secondPassSyntaxTree = RazorSyntaxTree.Parse(codeDocument.Source);
+ codeDocument.SetSyntaxTree(originalSyntaxTree);
+
+ var firstPass = new Mock<IRazorSyntaxTreePass>(MockBehavior.Strict);
+ firstPass.SetupGet(m => m.Order).Returns(0);
+ firstPass.SetupProperty(m => m.Engine);
+ firstPass.Setup(m => m.Execute(codeDocument, originalSyntaxTree)).Returns(firstPassSyntaxTree);
+
+ var secondPass = new Mock<IRazorSyntaxTreePass>(MockBehavior.Strict);
+ secondPass.SetupGet(m => m.Order).Returns(1);
+ secondPass.SetupProperty(m => m.Engine);
+ secondPass.Setup(m => m.Execute(codeDocument, firstPassSyntaxTree)).Returns(secondPassSyntaxTree);
+
+ var phase = new DefaultRazorSyntaxTreePhase();
+
+ var engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ b.Phases.Add(phase);
+
+ b.Features.Add(firstPass.Object);
+ b.Features.Add(secondPass.Object);
+ });
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ Assert.Same(secondPassSyntaxTree, codeDocument.GetSyntaxTree());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorTagHelperBinderPhaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorTagHelperBinderPhaseTest.cs
new file mode 100644
index 0000000000..0585198d3e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRazorTagHelperBinderPhaseTest.cs
@@ -0,0 +1,930 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRazorTagHelperBinderPhaseTest
+ {
+ [Fact]
+ public void Execute_CanHandleSingleLengthAddTagHelperDirective()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new TagHelperDescriptor[0]);
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+ var expectedDiagnostics = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(14 + Environment.NewLine.Length, 1, 14), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14 + Environment.NewLine.Length, 1, 14), contentLength: 1), "\"")
+ };
+
+ var content =
+ @"
+@addTagHelper """;
+ var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ var directiveValue = rewrittenTree.Root.Children.OfType<Block>().First().Children.Last() as Span;
+ var chunkGenerator = Assert.IsType<AddTagHelperChunkGenerator>(directiveValue.ChunkGenerator);
+ Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics);
+ }
+
+ [Fact]
+ public void Execute_CanHandleSingleLengthRemoveTagHelperDirective()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new TagHelperDescriptor[0]);
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+ var expectedDiagnostics = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1), "\"")
+ };
+
+ var content =
+ @"
+@removeTagHelper """;
+ var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ var directiveValue = rewrittenTree.Root.Children.OfType<Block>().First().Children.Last() as Span;
+ var chunkGenerator = Assert.IsType<RemoveTagHelperChunkGenerator>(directiveValue.ChunkGenerator);
+ Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics);
+ }
+
+ [Fact]
+ public void Execute_CanHandleSingleLengthTagHelperPrefix()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new TagHelperDescriptor[0]);
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+ var expectedDiagnostics = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
+ new SourceSpan(new SourceLocation(17 + Environment.NewLine.Length, 1, 17), contentLength: 1), "tagHelperPrefix", '\"', "\""),
+ };
+
+ var content =
+ @"
+@tagHelperPrefix """;
+ var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ var directiveValue = rewrittenTree.Root.Children.OfType<Block>().First().Children.Last() as Span;
+ var chunkGenerator = Assert.IsType<TagHelperPrefixDirectiveChunkGenerator>(directiveValue.ChunkGenerator);
+ Assert.Equal(expectedDiagnostics, chunkGenerator.Diagnostics);
+ }
+
+ [Fact]
+ public void Execute_RewritesTagHelpers()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "form",
+ typeName: "TestFormTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestInputTagHelper",
+ assemblyName: "TestAssembly"),
+ });
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var sourceDocument = CreateTestSourceDocument();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(rewrittenTree.Diagnostics);
+ Assert.Equal(3, rewrittenTree.Root.Children.Count);
+ var formTagHelper = Assert.IsType<TagHelperBlock>(rewrittenTree.Root.Children[2]);
+ Assert.Equal("form", formTagHelper.TagName);
+ Assert.Equal(3, formTagHelper.Children.Count);
+ var inputTagHelper = Assert.IsType<TagHelperBlock>(formTagHelper.Children[1]);
+ Assert.Equal("input", inputTagHelper.TagName);
+ }
+
+ [Fact]
+ public void Execute_DirectiveWithoutQuotes_RewritesTagHelpers_TagHelperMatchesElementTwice()
+ {
+ // Arrange
+ var descriptor = CreateTagHelperDescriptor(
+ tagName: "form",
+ typeName: "TestFormTagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ ruleBuilder => ruleBuilder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("a")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)),
+ ruleBuilder => ruleBuilder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("b")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)),
+ });
+
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new[] { descriptor });
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var content = @"
+@addTagHelper *, TestAssembly
+<form a=""hi"" b=""there"">
+</form>";
+
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(rewrittenTree.Diagnostics);
+ Assert.Equal(3, rewrittenTree.Root.Children.Count);
+
+ var formTagHelper = Assert.IsType<TagHelperBlock>(rewrittenTree.Root.Children[2]);
+ Assert.Equal("form", formTagHelper.TagName);
+ Assert.Equal(2, formTagHelper.Binding.GetBoundRules(descriptor).Count());
+ }
+
+ [Fact]
+ public void Execute_DirectiveWithQuotes_RewritesTagHelpers_TagHelperMatchesElementTwice()
+ {
+ // Arrange
+ var descriptor = CreateTagHelperDescriptor(
+ tagName: "form",
+ typeName: "TestFormTagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ ruleBuilder => ruleBuilder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("a")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)),
+ ruleBuilder => ruleBuilder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("b")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)),
+ });
+
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new[] { descriptor });
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var content = @"
+@addTagHelper ""*, TestAssembly""
+<form a=""hi"" b=""there"">
+</form>";
+
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var rewrittenTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(rewrittenTree.Diagnostics);
+ Assert.Equal(3, rewrittenTree.Root.Children.Count);
+
+ var formTagHelper = Assert.IsType<TagHelperBlock>(rewrittenTree.Root.Children[2]);
+ Assert.Equal("form", formTagHelper.TagName);
+ Assert.Equal(2, formTagHelper.Binding.GetBoundRules(descriptor).Count());
+ }
+
+ [Fact]
+ public void Execute_NoopsWhenNoTagHelperFeature()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create();
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+ var sourceDocument = CreateTestSourceDocument();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var outputTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(outputTree.Diagnostics);
+ Assert.Same(originalTree, outputTree);
+ }
+
+ [Fact]
+ public void Execute_NoopsWhenNoFeature()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ });
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+ var sourceDocument = CreateTestSourceDocument();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var outputTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(outputTree.Diagnostics);
+ Assert.Same(originalTree, outputTree);
+ }
+
+ [Fact]
+ public void Execute_NoopsWhenNoTagHelperDescriptorsAreResolved()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.Features.Add(new TestTagHelperFeature());
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ // No taghelper directives here so nothing is resolved.
+ var sourceDocument = TestRazorSourceDocument.Create("Hello, world");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var outputTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(outputTree.Diagnostics);
+ Assert.Same(originalTree, outputTree);
+ }
+
+ [Fact]
+ public void Execute_SetsTagHelperDocumentContext()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.Features.Add(new TestTagHelperFeature());
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ // No taghelper directives here so nothing is resolved.
+ var sourceDocument = TestRazorSourceDocument.Create("Hello, world");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ codeDocument.SetSyntaxTree(originalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var context = codeDocument.GetTagHelperContext();
+ Assert.Null(context.Prefix);
+ Assert.Empty(context.TagHelpers);
+ }
+
+ [Fact]
+ public void Execute_CombinesErrorsOnRewritingErrors()
+ {
+ // Arrange
+ var projectEngine = RazorProjectEngine.Create(builder =>
+ {
+ builder.AddTagHelpers(new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "form",
+ typeName: "TestFormTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestInputTagHelper",
+ assemblyName: "TestAssembly"),
+ });
+ });
+
+ var phase = new DefaultRazorTagHelperBinderPhase()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var content =
+ @"
+@addTagHelper *, TestAssembly
+<form>
+ <input value='Hello' type='text' />";
+ var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+
+ var initialError = RazorDiagnostic.Create(
+ new RazorDiagnosticDescriptor("RZ9999", () => "Initial test error", RazorDiagnosticSeverity.Error),
+ new SourceSpan(SourceLocation.Zero, contentLength: 1));
+ var expectedRewritingError = RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(Environment.NewLine.Length * 2 + 30, 2, 1), contentLength: 4), "form");
+
+ var erroredOriginalTree = RazorSyntaxTree.Create(originalTree.Root, originalTree.Source, new[] { initialError }, originalTree.Options);
+ codeDocument.SetSyntaxTree(erroredOriginalTree);
+
+ // Act
+ phase.Execute(codeDocument);
+
+ // Assert
+ var outputTree = codeDocument.GetSyntaxTree();
+ Assert.Empty(originalTree.Diagnostics);
+ Assert.NotSame(erroredOriginalTree, outputTree);
+ Assert.Equal(new[] { initialError, expectedRewritingError }, outputTree.Diagnostics);
+ }
+
+ private static string AssemblyA => "TestAssembly";
+
+ private static string AssemblyB => "AnotherAssembly";
+
+ private static TagHelperDescriptor Valid_PlainTagHelperDescriptor
+ {
+ get
+ {
+ return CreateTagHelperDescriptor(
+ tagName: "valid_plain",
+ typeName: "Microsoft.AspNetCore.Razor.TagHelpers.ValidPlainTagHelper",
+ assemblyName: AssemblyA);
+ }
+ }
+
+ private static TagHelperDescriptor Valid_InheritedTagHelperDescriptor
+ {
+ get
+ {
+ return CreateTagHelperDescriptor(
+ tagName: "valid_inherited",
+ typeName: "Microsoft.AspNetCore.Razor.TagHelpers.ValidInheritedTagHelper",
+ assemblyName: AssemblyA);
+ }
+ }
+
+ private static TagHelperDescriptor String_TagHelperDescriptor
+ {
+ get
+ {
+ // We're treating 'string' as a TagHelper so we can test TagHelpers in multiple assemblies without
+ // building a separate assembly with a single TagHelper.
+ return CreateTagHelperDescriptor(
+ tagName: "string",
+ typeName: "System.String",
+ assemblyName: AssemblyB);
+ }
+ }
+
+ public static TheoryData ProcessTagHelperPrefixData
+ {
+ get
+ {
+ // source, expected prefix
+ return new TheoryData<string, string>
+ {
+ {
+ $@"
+@tagHelperPrefix """"
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidPlain*, TestAssembly",
+ null
+ },
+ {
+ $@"
+@tagHelperPrefix th:
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidPlain*, {AssemblyA}",
+ "th:"
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@tagHelperPrefix th:",
+ "th:"
+ },
+ {
+ $@"
+@tagHelperPrefix th-
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidPlain*, {AssemblyA}
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidInherited*, {AssemblyA}",
+ "th-"
+ },
+ {
+ $@"
+@tagHelperPrefix
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidPlain*, {AssemblyA}
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidInherited*, {AssemblyA}",
+ null
+ },
+ {
+ $@"
+@tagHelperPrefix ""th""
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}",
+ "th"
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@tagHelperPrefix th:-
+@addTagHelper *, {AssemblyB}",
+ "th:-"
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ProcessTagHelperPrefixData))]
+ public void DirectiveVisitor_ExtractsPrefixFromSyntaxTree(
+ string source,
+ string expectedPrefix)
+ {
+ // Arrange
+ var sourceDocument = TestRazorSourceDocument.Create(source, filePath: "TestFile");
+ var parser = new RazorParser();
+ var syntaxTree = parser.Parse(sourceDocument);
+ var visitor = new DefaultRazorTagHelperBinderPhase.DirectiveVisitor(tagHelpers: new List<TagHelperDescriptor>());
+
+ // Act
+ visitor.VisitBlock(syntaxTree.Root);
+
+ // Assert
+ Assert.Equal(expectedPrefix, visitor.TagHelperPrefix);
+ }
+
+ public static TheoryData ProcessTagHelperMatchesData
+ {
+ get
+ {
+ // source, taghelpers, expected descriptors
+ return new TheoryData<string, TagHelperDescriptor[], TagHelperDescriptor[]>
+ {
+ {
+ $@"
+@addTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor },
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper *, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, String_TagHelperDescriptor },
+ new [] { String_TagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}
+@addTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_InheritedTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_InheritedTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_InheritedTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidPlain*, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper Microsoft.AspNetCore.Razor.TagHelpers.*, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper Microsoft.AspNetCore.Razor.TagHelpers.ValidP*, {AssemblyA}
+@addTagHelper *, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, },
+ new [] { Valid_InheritedTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper Str*, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper *, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper System.{String_TagHelperDescriptor.Name}, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, String_TagHelperDescriptor, },
+ new [] { Valid_PlainTagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper Microsoft.*, {AssemblyA}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, String_TagHelperDescriptor },
+ new [] { String_TagHelperDescriptor }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper ?Microsoft*, {AssemblyA}
+@removeTagHelper System.{String_TagHelperDescriptor.Name}, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, String_TagHelperDescriptor },
+ new []
+ {
+ Valid_InheritedTagHelperDescriptor,
+ Valid_PlainTagHelperDescriptor,
+ String_TagHelperDescriptor
+ }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper TagHelper*, {AssemblyA}
+@removeTagHelper System.{String_TagHelperDescriptor.Name}, {AssemblyB}",
+ new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor, String_TagHelperDescriptor },
+ new []
+ {
+ Valid_InheritedTagHelperDescriptor,
+ Valid_PlainTagHelperDescriptor,
+ String_TagHelperDescriptor
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ProcessTagHelperMatchesData))]
+ public void DirectiveVisitor_FiltersTagHelpersByDirectives(
+ string source,
+ object tagHelpers,
+ object expectedDescriptors)
+ {
+ // Arrange
+ var expected = (TagHelperDescriptor[])expectedDescriptors;
+ var sourceDocument = TestRazorSourceDocument.Create(source, filePath: "TestFile");
+ var parser = new RazorParser();
+ var syntaxTree = parser.Parse(sourceDocument);
+ var visitor = new DefaultRazorTagHelperBinderPhase.DirectiveVisitor((TagHelperDescriptor[])tagHelpers);
+
+ // Act
+ visitor.VisitBlock(syntaxTree.Root);
+
+ // Assert
+ Assert.Equal(expected.Count(), visitor.Matches.Count());
+
+ foreach (var expectedDescriptor in expected)
+ {
+ Assert.Contains(expectedDescriptor, visitor.Matches, TagHelperDescriptorComparer.Default);
+ }
+ }
+
+ public static TheoryData ProcessTagHelperMatches_EmptyResultData
+ {
+ get
+ {
+ // source, taghelpers
+ return new TheoryData<string, IEnumerable<TagHelperDescriptor>>
+ {
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper *, {AssemblyA}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}
+@removeTagHelper {Valid_InheritedTagHelperDescriptor.Name}, {AssemblyA}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper *, {AssemblyA}
+@removeTagHelper *, {AssemblyB}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ String_TagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@addTagHelper *, {AssemblyB}
+@removeTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}
+@removeTagHelper {Valid_InheritedTagHelperDescriptor.Name}, {AssemblyA}
+@removeTagHelper {String_TagHelperDescriptor.Name}, {AssemblyB}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ String_TagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@removeTagHelper *, {AssemblyA}
+@removeTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}",
+ new TagHelperDescriptor[0]
+ },
+ {
+ $@"
+@addTagHelper *, {AssemblyA}
+@removeTagHelper Mic*, {AssemblyA}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper Mic*, {AssemblyA}
+@removeTagHelper {Valid_PlainTagHelperDescriptor.Name}, {AssemblyA}
+@removeTagHelper {Valid_InheritedTagHelperDescriptor.Name}, {AssemblyA}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor
+ }
+ },
+ {
+ $@"
+@addTagHelper Microsoft.*, {AssemblyA}
+@addTagHelper System.*, {AssemblyB}
+@removeTagHelper Microsoft.AspNetCore.Razor.TagHelpers*, {AssemblyA}
+@removeTagHelper System.*, {AssemblyB}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ String_TagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper ?icrosoft.*, {AssemblyA}
+@addTagHelper ?ystem.*, {AssemblyB}
+@removeTagHelper *?????r, {AssemblyA}
+@removeTagHelper Sy??em.*, {AssemblyB}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ String_TagHelperDescriptor,
+ }
+ },
+ {
+ $@"
+@addTagHelper ?i?crosoft.*, {AssemblyA}
+@addTagHelper ??ystem.*, {AssemblyB}",
+ new TagHelperDescriptor[]
+ {
+ Valid_PlainTagHelperDescriptor,
+ Valid_InheritedTagHelperDescriptor,
+ String_TagHelperDescriptor,
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ProcessTagHelperMatches_EmptyResultData))]
+ public void ProcessDirectives_CanReturnEmptyDescriptorsBasedOnDirectiveDescriptors(
+ string source,
+ object tagHelpers)
+ {
+ // Arrange
+ var sourceDocument = TestRazorSourceDocument.Create(source, filePath: "TestFile");
+ var parser = new RazorParser();
+ var syntaxTree = parser.Parse(sourceDocument);
+ var visitor = new DefaultRazorTagHelperBinderPhase.DirectiveVisitor((TagHelperDescriptor[])tagHelpers);
+
+ // Act
+ visitor.VisitBlock(syntaxTree.Root);
+
+ // Assert
+ Assert.Empty(visitor.Matches);
+ }
+
+ private static TagHelperDescriptor CreatePrefixedValidPlainDescriptor(string prefix)
+ {
+ return Valid_PlainTagHelperDescriptor;
+ }
+
+ private static TagHelperDescriptor CreatePrefixedValidInheritedDescriptor(string prefix)
+ {
+ return Valid_InheritedTagHelperDescriptor;
+ }
+
+ private static TagHelperDescriptor CreatePrefixedStringDescriptor(string prefix)
+ {
+ return String_TagHelperDescriptor;
+ }
+
+ private static RazorSourceDocument CreateTestSourceDocument()
+ {
+ var content =
+ @"
+@addTagHelper *, TestAssembly
+<form>
+ <input value='Hello' type='text' />
+</form>";
+ var sourceDocument = TestRazorSourceDocument.Create(content, filePath: null);
+ return sourceDocument;
+ }
+
+ private static TagHelperDescriptor CreateTagHelperDescriptor(
+ string tagName,
+ string typeName,
+ string assemblyName,
+ IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null,
+ IEnumerable<Action<TagMatchingRuleDescriptorBuilder>> ruleBuilders = null)
+ {
+ var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
+ builder.TypeName(typeName);
+
+ if (attributes != null)
+ {
+ foreach (var attributeBuilder in attributes)
+ {
+ builder.BoundAttributeDescriptor(attributeBuilder);
+ }
+ }
+
+ if (ruleBuilders != null)
+ {
+ foreach (var ruleBuilder in ruleBuilders)
+ {
+ builder.TagMatchingRuleDescriptor(innerRuleBuilder =>
+ {
+ innerRuleBuilder.RequireTagName(tagName);
+ ruleBuilder(innerRuleBuilder);
+ });
+ }
+ }
+ else
+ {
+ builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
+ }
+
+ var descriptor = builder.Build();
+
+ return descriptor;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRequiredAttributeDescriptorBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRequiredAttributeDescriptorBuilderTest.cs
new file mode 100644
index 0000000000..f847f6ae3c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DefaultRequiredAttributeDescriptorBuilderTest.cs
@@ -0,0 +1,44 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DefaultRequiredAttributeDescriptorBuilderTest
+ {
+ [Fact]
+ public void Build_DisplayNameIsName_NameComparisonFullMatch()
+ {
+ // Arrange
+ var builder = new DefaultRequiredAttributeDescriptorBuilder();
+
+ builder
+ .Name("asp-action")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch);
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal("asp-action", descriptor.DisplayName);
+ }
+
+ [Fact]
+ public void Build_DisplayNameIsNameWithDots_NameComparisonPrefixMatch()
+ {
+ // Arrange
+ var builder = new DefaultRequiredAttributeDescriptorBuilder();
+
+ builder
+ .Name("asp-route-")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch);
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal("asp-route-...", descriptor.DisplayName);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorBuilderExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorBuilderExtensionsTest.cs
new file mode 100644
index 0000000000..ffcb4f8ba9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorBuilderExtensionsTest.cs
@@ -0,0 +1,122 @@
+// Copyright(c) .NET Foundation.All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DirectiveDescriptorBuilderExtensionsTest
+ {
+ [Fact]
+ public void AddMemberToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddMemberToken());
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Member, token.Kind);
+ Assert.False(token.Optional);
+ Assert.Null(token.Name);
+ Assert.Null(token.Description);
+ }
+
+ [Fact]
+ public void AddNamespaceToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddNamespaceToken("Name", "Description"));
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Namespace, token.Kind);
+ Assert.False(token.Optional);
+ Assert.Equal("Name", token.Name);
+ Assert.Equal("Description", token.Description);
+ }
+
+ [Fact]
+ public void AddStringToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddStringToken());
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.String, token.Kind);
+ Assert.False(token.Optional);
+ Assert.Null(token.Name);
+ Assert.Null(token.Description);
+ }
+
+ [Fact]
+ public void AddTypeToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddTypeToken("Name", "Description"));
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Type, token.Kind);
+ Assert.False(token.Optional);
+ Assert.Equal("Name", token.Name);
+ Assert.Equal("Description", token.Description);
+ }
+
+ [Fact]
+ public void AddOptionalTypeToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddOptionalTypeToken());
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Type, token.Kind);
+ Assert.True(token.Optional);
+ Assert.Null(token.Name);
+ Assert.Null(token.Description);
+ }
+
+ [Fact]
+ public void AddOptionalMemberToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddOptionalMemberToken("Name", "Description"));
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Member, token.Kind);
+ Assert.True(token.Optional);
+ Assert.Equal("Name", token.Name);
+ Assert.Equal("Description", token.Description);
+ }
+
+ [Fact]
+ public void AddOptionalNamespaceToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddOptionalNamespaceToken());
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.Namespace, token.Kind);
+ Assert.True(token.Optional);
+ Assert.Null(token.Name);
+ Assert.Null(token.Description);
+ }
+
+ [Fact]
+ public void AddOptionalStringToken_AddsToken()
+ {
+ // Arrange & Act
+ var descriptor = DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddOptionalStringToken("Name", "Description"));
+
+ // Assert
+ var token = Assert.Single(descriptor.Tokens);
+ Assert.Equal(DirectiveTokenKind.String, token.Kind);
+ Assert.True(token.Optional);
+ Assert.Equal("Name", token.Name);
+ Assert.Equal("Description", token.Description);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorTest.cs
new file mode 100644
index 0000000000..a5bb3c8434
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveDescriptorTest.cs
@@ -0,0 +1,150 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DirectiveDescriptorTest
+ {
+ [Fact]
+ public void CreateDirective_CreatesDirective_WithProvidedKind()
+ {
+ // Arrange & Act
+ var directive = DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine);
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.SingleLine, directive.Kind);
+ }
+
+ [Fact]
+ public void CreateDirective_WithConfigure_CreatesDirective_WithProvidedKind()
+ {
+ // Arrange
+ var called = false;
+ Action<IDirectiveDescriptorBuilder> configure = b => { called = true; };
+
+ // Act
+ var directive = DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine, configure);
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.SingleLine, directive.Kind);
+ Assert.True(called);
+ }
+
+ [Fact]
+ public void CreateSingleLineDirective_CreatesSingleLineDirective()
+ {
+ // Arrange & Act
+ var directive = DirectiveDescriptor.CreateSingleLineDirective("test");
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.SingleLine, directive.Kind);
+ }
+
+ [Fact]
+ public void CreateSingleLineDirective_WithConfigure_CreatesSingleLineDirective()
+ {
+ // Arrange
+ var called = false;
+ Action<IDirectiveDescriptorBuilder> configure = b => { called = true; };
+
+ // Act
+ var directive = DirectiveDescriptor.CreateSingleLineDirective("test", configure);
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.SingleLine, directive.Kind);
+ Assert.True(called);
+ }
+
+ [Fact]
+ public void CreateRazorBlockDirective_CreatesRazorBlockDirective()
+ {
+ // Arrange & Act
+ var directive = DirectiveDescriptor.CreateRazorBlockDirective("test");
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.RazorBlock, directive.Kind);
+ }
+
+ [Fact]
+ public void CreateRazorBlockDirective_WithConfigure_CreatesRazorBlockDirective()
+ {
+ // Arrange
+ var called = false;
+ Action<IDirectiveDescriptorBuilder> configure = b => { called = true; };
+
+ // Act
+ var directive = DirectiveDescriptor.CreateRazorBlockDirective("test", configure);
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.RazorBlock, directive.Kind);
+ Assert.True(called);
+ }
+
+ [Fact]
+ public void CreateCodeBlockDirective_CreatesCodeBlockDirective()
+ {
+ // Arrange & Act
+ var directive = DirectiveDescriptor.CreateCodeBlockDirective("test");
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.CodeBlock, directive.Kind);
+ }
+
+ [Fact]
+ public void CreateCodeBlockDirective_WithConfigure_CreatesCodeBlockDirective()
+ {
+ // Arrange
+ var called = false;
+ Action<IDirectiveDescriptorBuilder> configure = b => { called = true; };
+
+ // Act
+ var directive = DirectiveDescriptor.CreateCodeBlockDirective("test", configure);
+
+ // Assert
+ Assert.Equal("test", directive.Directive);
+ Assert.Equal(DirectiveKind.CodeBlock, directive.Kind);
+ Assert.True(called);
+ }
+
+ [Fact]
+ public void Build_ValidatesDirectiveKeyword_EmptyIsInvalid()
+ {
+ // Arrange & Act
+ var ex = Assert.Throws<InvalidOperationException>(() => DirectiveDescriptor.CreateSingleLineDirective(""));
+
+ // Assert
+ Assert.Equal("Invalid directive keyword ''. Directives must have a non-empty keyword that consists only of letters.", ex.Message);
+ }
+
+ [Fact]
+ public void Build_ValidatesDirectiveKeyword_InvalidCharacter()
+ {
+ // Arrange & Act
+ var ex = Assert.Throws<InvalidOperationException>(() => DirectiveDescriptor.CreateSingleLineDirective("test_directive"));
+
+ // Assert
+ Assert.Equal("Invalid directive keyword 'test_directive'. Directives must have a non-empty keyword that consists only of letters.", ex.Message);
+ }
+
+ [Fact]
+ public void Build_ValidatesDirectiveName_NonOptionalTokenFollowsOptionalToken()
+ {
+ // Arrange & Act
+ var ex = Assert.Throws<InvalidOperationException>(
+ () => DirectiveDescriptor.CreateSingleLineDirective("test", b => { b.AddOptionalMemberToken(); b.AddMemberToken(); }));
+
+ // Assert
+ Assert.Equal("A non-optional directive token cannot follow an optional directive token.", ex.Message);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveRemovalOptimizationPassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveRemovalOptimizationPassTest.cs
new file mode 100644
index 0000000000..3e831b7d23
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveRemovalOptimizationPassTest.cs
@@ -0,0 +1,135 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DirectiveRemovalOptimizationPassTest
+ {
+ [Fact]
+ public void Execute_Custom_RemovesDirectiveNodeFromDocument()
+ {
+ // Arrange
+ var content = "@custom \"Hello\"";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var defaultEngine = RazorProjectEngine.Create(b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, d => d.AddStringToken()));
+ }).Engine;
+ var documentNode = Lower(codeDocument, defaultEngine);
+ var pass = new DirectiveRemovalOptimizationPass()
+ {
+ Engine = defaultEngine,
+ };
+
+ // Act
+ pass.Execute(codeDocument, documentNode);
+
+ // Assert
+ Children(documentNode,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+ var @namespace = documentNode.Children[0];
+ Children(@namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+ var @class = @namespace.Children[0];
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ Assert.Empty(method.Children);
+ }
+
+ [Fact]
+ public void Execute_MultipleCustomDirectives_RemovesDirectiveNodesFromDocument()
+ {
+ // Arrange
+ var content = "@custom \"Hello\"" + Environment.NewLine + "@custom \"World\"";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var defaultEngine = RazorProjectEngine.Create(b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, d => d.AddStringToken()));
+ }).Engine;
+ var documentNode = Lower(codeDocument, defaultEngine);
+ var pass = new DirectiveRemovalOptimizationPass()
+ {
+ Engine = defaultEngine,
+ };
+
+ // Act
+ pass.Execute(codeDocument, documentNode);
+
+ // Assert
+ Children(documentNode,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+ var @namespace = documentNode.Children[0];
+ Children(@namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+ var @class = @namespace.Children[0];
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ Assert.Empty(method.Children);
+ }
+
+ [Fact]
+ public void Execute_DirectiveWithError_PreservesDiagnosticsAndRemovesDirectiveNodeFromDocument()
+ {
+ // Arrange
+ var content = "@custom \"Hello\"";
+ var expectedDiagnostic = RazorDiagnostic.Create(new RazorDiagnosticDescriptor("RZ9999", () => "Some diagnostic message.", RazorDiagnosticSeverity.Error), SourceSpan.Undefined);
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+ var defaultEngine = RazorProjectEngine.Create(b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, d => d.AddStringToken()));
+ }).Engine;
+ var documentNode = Lower(codeDocument, defaultEngine);
+
+ // Add the diagnostic to the directive node.
+ var directiveNode = documentNode.FindDescendantNodes<DirectiveIntermediateNode>().Single();
+ directiveNode.Diagnostics.Add(expectedDiagnostic);
+
+ var pass = new DirectiveRemovalOptimizationPass()
+ {
+ Engine = defaultEngine,
+ };
+
+ // Act
+ pass.Execute(codeDocument, documentNode);
+
+ // Assert
+ var diagnostic = Assert.Single(documentNode.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+
+ Children(documentNode,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+ var @namespace = documentNode.Children[0];
+ Children(@namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+ var @class = @namespace.Children[0];
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ Assert.Empty(method.Children);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
+ {
+ for (var i = 0; i < engine.Phases.Count; i++)
+ {
+ var phase = engine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorDirectiveClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ var documentNode = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(documentNode);
+
+ return documentNode;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs
new file mode 100644
index 0000000000..0ddfa731e4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs
@@ -0,0 +1,66 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test
+{
+ public class DirectiveTokenEditHandlerTest
+ {
+ [Theory]
+ [InlineData(0, 4, "")] // "Namespace"
+ [InlineData(4, 0, "Other")] // "SomeOtherNamespace"
+ [InlineData(0, 4, "Other")] // "OtherNamespace"
+ public void CanAcceptChange_ProvisionallyAcceptsNonWhitespaceChanges(int index, int length, string newText)
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var directiveTokenHandler = new TestDirectiveTokenEditHandler();
+ var target = factory.Span(SpanKindInternal.Code, "SomeNamespace", markup: false)
+ .With(directiveTokenHandler)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace);
+ var sourceChange = new SourceChange(index, length, newText);
+
+ // Act
+ var result = directiveTokenHandler.CanAcceptChange(target, sourceChange);
+
+ // Assert
+ Assert.Equal(PartialParseResultInternal.Accepted | PartialParseResultInternal.Provisional, result);
+ }
+
+ [Theory]
+ [InlineData(4, 1, "")] // "SomeNamespace"
+ [InlineData(9, 0, " ")] // "Some Name space"
+ [InlineData(9, 5, " Space")] // "Some Name Space"
+ public void CanAcceptChange_RejectsWhitespaceChanges(int index, int length, string newText)
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var directiveTokenHandler = new TestDirectiveTokenEditHandler();
+ var target = factory.Span(SpanKindInternal.Code, "Some Namespace", markup: false)
+ .With(directiveTokenHandler)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace);
+ var sourceChange = new SourceChange(index, length, newText);
+
+ // Act
+ var result = directiveTokenHandler.CanAcceptChange(target, sourceChange);
+
+ // Assert
+ Assert.Equal(PartialParseResultInternal.Rejected, result);
+ }
+
+ private class TestDirectiveTokenEditHandler : DirectiveTokenEditHandler
+ {
+ public TestDirectiveTokenEditHandler() : base(content => SpanConstructor.TestTokenizer(content))
+ {
+ }
+
+ public new PartialParseResultInternal CanAcceptChange(Span target, SourceChange change)
+ => base.CanAcceptChange(target, change);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DocumentClassifierPassBaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DocumentClassifierPassBaseTest.cs
new file mode 100644
index 0000000000..5030af7d02
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/DocumentClassifierPassBaseTest.cs
@@ -0,0 +1,300 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class DocumentClassifierPassBaseTest
+ {
+ public RazorEngine Engine
+ {
+ get
+ {
+ var projectEngine = RazorProjectEngine.Create();
+ return projectEngine.Engine;
+ }
+ }
+
+ [Fact]
+ public void Execute_HasDocumentKind_IgnoresDocument()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ DocumentKind = "ignore",
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var pass = new TestDocumentClassifierPass();
+ pass.Engine = Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Equal("ignore", documentNode.DocumentKind);
+ NoChildren(documentNode);
+ }
+
+ [Fact]
+ public void Execute_NoMatch_IgnoresDocument()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var pass = new TestDocumentClassifierPass()
+ {
+ Engine = Engine,
+ ShouldMatch = false,
+ };
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Null(documentNode.DocumentKind);
+ NoChildren(documentNode);
+ }
+
+ [Fact]
+ public void Execute_Match_AddsGlobalTargetExtensions()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var expected = new ICodeTargetExtension[]
+ {
+ new MyExtension1(),
+ new MyExtension2(),
+ };
+
+ var pass = new TestDocumentClassifierPass();
+ pass.Engine = RazorProjectEngine.CreateEmpty(b =>
+ {
+ for (var i = 0; i < expected.Length; i++)
+ {
+ b.AddTargetExtension(expected[i]);
+ }
+ }).Engine;
+
+ ICodeTargetExtension[] extensions = null;
+
+ pass.CodeTargetCallback = (builder) => extensions = builder.TargetExtensions.ToArray();
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Equal(expected, extensions);
+ }
+
+ [Fact]
+ public void Execute_Match_SetsDocumentType_AndCreatesStructure()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var pass = new TestDocumentClassifierPass();
+ pass.Engine = Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ Assert.Equal("test", documentNode.DocumentKind);
+ Assert.NotNull(documentNode.Target);
+
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ NoChildren(method);
+ }
+
+ [Fact]
+ public void Execute_AddsUsingsToNamespace()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var builder = IntermediateNodeBuilder.Create(documentNode);
+ builder.Add(new UsingDirectiveIntermediateNode());
+
+ var pass = new TestDocumentClassifierPass();
+ pass.Engine = Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ Children(
+ @namespace,
+ n => Assert.IsType<UsingDirectiveIntermediateNode>(n),
+ n => Assert.IsType<ClassDeclarationIntermediateNode>(n));
+ }
+
+ [Fact]
+ public void Execute_AddsTheRestToMethod()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var builder = IntermediateNodeBuilder.Create(documentNode);
+ builder.Add(new HtmlContentIntermediateNode());
+ builder.Add(new CSharpCodeIntermediateNode());
+
+ var pass = new TestDocumentClassifierPass();
+ pass.Engine = Engine;
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ Children(
+ method,
+ n => Assert.IsType<HtmlContentIntermediateNode>(n),
+ n => Assert.IsType<CSharpCodeIntermediateNode>(n));
+ }
+
+ [Fact]
+ public void Execute_CanInitializeDefaults()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var builder = IntermediateNodeBuilder.Create(documentNode);
+ builder.Add(new HtmlContentIntermediateNode());
+ builder.Add(new CSharpCodeIntermediateNode());
+
+ var pass = new TestDocumentClassifierPass()
+ {
+ Engine = Engine,
+ Namespace = "TestNamespace",
+ Class = "TestClass",
+ Method = "TestMethod",
+ };
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ Assert.Equal("TestNamespace", @namespace.Content);
+
+ var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
+ Assert.Equal("TestClass", @class.ClassName);
+
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ Assert.Equal("TestMethod", method.MethodName);
+ }
+
+ [Fact]
+ public void Execute_AddsPrimaryAnnotations()
+ {
+ // Arrange
+ var documentNode = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.CreateDefault(),
+ };
+
+ var builder = IntermediateNodeBuilder.Create(documentNode);
+ builder.Add(new HtmlContentIntermediateNode());
+ builder.Add(new CSharpCodeIntermediateNode());
+
+ var pass = new TestDocumentClassifierPass()
+ {
+ Engine = Engine,
+ Namespace = "TestNamespace",
+ Class = "TestClass",
+ Method = "TestMethod",
+ };
+
+ // Act
+ pass.Execute(TestRazorCodeDocument.CreateEmpty(), documentNode);
+
+ // Assert
+ var @namespace = SingleChild<NamespaceDeclarationIntermediateNode>(documentNode);
+ AnnotationEquals(@namespace, CommonAnnotations.PrimaryNamespace);
+
+ var @class = SingleChild<ClassDeclarationIntermediateNode>(@namespace);
+ AnnotationEquals(@class, CommonAnnotations.PrimaryClass);
+
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+ AnnotationEquals(method, CommonAnnotations.PrimaryMethod);
+ }
+
+ private class TestDocumentClassifierPass : DocumentClassifierPassBase
+ {
+ public override int Order => IntermediateNodePassBase.DefaultFeatureOrder;
+
+ public bool ShouldMatch { get; set; } = true;
+
+ public Action<CodeTargetBuilder> CodeTargetCallback { get; set; }
+
+ public string Namespace { get; set; }
+
+ public string Class { get; set; }
+
+ public string Method { get; set; }
+
+ protected override string DocumentKind => "test";
+
+ protected override bool IsMatch(RazorCodeDocument codeDocument, DocumentIntermediateNode documentNode)
+ {
+ return ShouldMatch;
+ }
+
+ protected override void OnDocumentStructureCreated(
+ RazorCodeDocument codeDocument,
+ NamespaceDeclarationIntermediateNode @namespace,
+ ClassDeclarationIntermediateNode @class,
+ MethodDeclarationIntermediateNode method)
+ {
+ @namespace.Content = Namespace;
+ @class.ClassName = Class;
+ @method.MethodName = Method;
+ }
+
+ protected override void ConfigureTarget(CodeTargetBuilder builder)
+ {
+ CodeTargetCallback?.Invoke(builder);
+ }
+ }
+
+ private class MyExtension1 : ICodeTargetExtension
+ {
+ }
+
+ private class MyExtension2 : ICodeTargetExtension
+ {
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultMetadataIdentifierFeatureTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultMetadataIdentifierFeatureTest.cs
new file mode 100644
index 0000000000..747fa9ec89
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultMetadataIdentifierFeatureTest.cs
@@ -0,0 +1,72 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class DefaultMetadataIdentifierFeatureTest
+ {
+ [Fact]
+ public void GetIdentifier_ReturnsNull_ForNullRelativePath()
+ {
+ // Arrange
+ var sourceDocument = RazorSourceDocument.Create("content", new RazorSourceDocumentProperties("Test.cshtml", null));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var feature = new DefaultMetadataIdentifierFeature()
+ {
+ Engine = RazorProjectEngine.Create().Engine,
+ };
+
+ // Act
+ var result = feature.GetIdentifier(codeDocument, sourceDocument);
+
+ // Assert
+ Assert.Null(result);
+ }
+
+ [Fact]
+ public void GetIdentifier_ReturnsNull_ForEmptyRelativePath()
+ {
+ // Arrange
+ var sourceDocument = RazorSourceDocument.Create("content", new RazorSourceDocumentProperties("Test.cshtml", string.Empty));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var feature = new DefaultMetadataIdentifierFeature()
+ {
+ Engine = RazorProjectEngine.Create().Engine,
+ };
+
+ // Act
+ var result = feature.GetIdentifier(codeDocument, sourceDocument);
+
+ // Assert
+ Assert.Null(result);
+ }
+
+ [Theory]
+ [InlineData("Test.cshtml", "/Test.cshtml")]
+ [InlineData("/Test.cshtml", "/Test.cshtml")]
+ [InlineData("\\Test.cshtml", "/Test.cshtml")]
+ [InlineData("\\About\\Test.cshtml", "/About/Test.cshtml")]
+ [InlineData("\\About\\Test\\cshtml", "/About/Test/cshtml")]
+ public void GetIdentifier_SanitizesRelativePath(string relativePath, string expected)
+ {
+ // Arrange
+ var sourceDocument = RazorSourceDocument.Create("content", new RazorSourceDocumentProperties("Test.cshtml", relativePath));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var feature = new DefaultMetadataIdentifierFeature()
+ {
+ Engine = RazorProjectEngine.Create().Engine,
+ };
+
+ // Act
+ var result = feature.GetIdentifier(codeDocument, sourceDocument);
+
+ // Assert
+ Assert.Equal(expected, result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperOptimizationPassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperOptimizationPassTest.cs
new file mode 100644
index 0000000000..7321c473cb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperOptimizationPassTest.cs
@@ -0,0 +1,128 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class DefaultTagHelperOptimizationPassTest
+ {
+ [Fact]
+ public void DefaultTagHelperOptimizationPass_Execute_ReplacesChildren()
+ {
+ // Arrange
+ var codeDocument = CreateDocument(@"
+@addTagHelper TestTagHelper, TestAssembly
+<p foo=""17"" attr=""value"">");
+
+ var tagHelpers = new[]
+ {
+ TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly")
+ .TypeName("TestTagHelper")
+ .BoundAttributeDescriptor(attribute => attribute
+ .Name("Foo")
+ .TypeName("System.Int32")
+ .PropertyName("FooProp"))
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build()
+ };
+
+ var engine = CreateEngine(tagHelpers);
+ var pass = new DefaultTagHelperOptimizationPass()
+ {
+ Engine = engine
+ };
+
+ var irDocument = CreateIRDocument(engine, codeDocument);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ var @class = irDocument.FindPrimaryClass();
+ Assert.IsType<DefaultTagHelperRuntimeIntermediateNode>(@class.Children[0]);
+
+ var fieldDeclaration = Assert.IsType<FieldDeclarationIntermediateNode>(@class.Children[1]);
+ Assert.Equal(bool.TrueString, fieldDeclaration.Annotations[CommonAnnotations.DefaultTagHelperExtension.TagHelperField]);
+ Assert.Equal("__TestTagHelper", fieldDeclaration.FieldName);
+ Assert.Equal("global::TestTagHelper", fieldDeclaration.FieldType);
+ Assert.Equal("private", fieldDeclaration.Modifiers.First());
+
+ var tagHelper = FindTagHelperNode(irDocument);
+ Assert.Equal(5, tagHelper.Children.Count);
+
+ var body = Assert.IsType<DefaultTagHelperBodyIntermediateNode>(tagHelper.Children[0]);
+ Assert.Equal("p", body.TagName);
+ Assert.Equal(TagMode.StartTagAndEndTag, body.TagMode);
+
+ var create = Assert.IsType<DefaultTagHelperCreateIntermediateNode>(tagHelper.Children[1]);
+ Assert.Equal("__TestTagHelper", create.FieldName);
+ Assert.Equal("TestTagHelper", create.TypeName);
+ Assert.Equal(tagHelpers[0], create.TagHelper, TagHelperDescriptorComparer.CaseSensitive);
+
+ var property = Assert.IsType<DefaultTagHelperPropertyIntermediateNode>(tagHelper.Children[2]);
+ Assert.Equal("foo", property.AttributeName);
+ Assert.Equal(AttributeStructure.DoubleQuotes, property.AttributeStructure);
+ Assert.Equal(tagHelpers[0].BoundAttributes[0], property.BoundAttribute, BoundAttributeDescriptorComparer.CaseSensitive);
+ Assert.Equal("__TestTagHelper", property.FieldName);
+ Assert.False(property.IsIndexerNameMatch);
+ Assert.Equal("FooProp", property.PropertyName);
+ Assert.Equal(tagHelpers[0], property.TagHelper, TagHelperDescriptorComparer.CaseSensitive);
+
+ var htmlAttribute = Assert.IsType<DefaultTagHelperHtmlAttributeIntermediateNode>(tagHelper.Children[3]);
+ Assert.Equal("attr", htmlAttribute.AttributeName);
+ Assert.Equal(AttributeStructure.DoubleQuotes, htmlAttribute.AttributeStructure);
+
+ Assert.IsType<DefaultTagHelperExecuteIntermediateNode>(tagHelper.Children[4]);
+ }
+
+ private RazorCodeDocument CreateDocument(string content)
+ {
+ var source = RazorSourceDocument.Create(content, "test.cshtml");
+ return RazorCodeDocument.Create(source);
+ }
+
+ private RazorEngine CreateEngine(params TagHelperDescriptor[] tagHelpers)
+ {
+ return RazorProjectEngine.Create(b =>
+ {
+ b.Features.Add(new TestTagHelperFeature(tagHelpers));
+ }).Engine;
+ }
+
+ private DocumentIntermediateNode CreateIRDocument(RazorEngine engine, RazorCodeDocument codeDocument)
+ {
+ for (var i = 0; i < engine.Phases.Count; i++)
+ {
+ var phase = engine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorDirectiveClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ return codeDocument.GetDocumentIntermediateNode();
+ }
+
+ private TagHelperIntermediateNode FindTagHelperNode(IntermediateNode node)
+ {
+ var visitor = new TagHelperNodeVisitor();
+ visitor.Visit(node);
+ return visitor.Node;
+ }
+
+ private class TagHelperNodeVisitor : IntermediateNodeWalker
+ {
+ public TagHelperIntermediateNode Node { get; set; }
+
+ public override void VisitTagHelper(TagHelperIntermediateNode node)
+ {
+ Node = node;
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs
new file mode 100644
index 0000000000..6372657d9c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs
@@ -0,0 +1,1210 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class DefaultTagHelperTargetExtensionTest
+ {
+ private static readonly TagHelperDescriptor StringPropertyTagHelper = CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("StringProp")
+ .TypeName("System.String"),
+ });
+
+ private static readonly TagHelperDescriptor IntPropertyTagHelper = CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("IntProp")
+ .TypeName("System.Int32"),
+ });
+
+ private static readonly TagHelperDescriptor StringIndexerTagHelper = CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("StringIndexer")
+ .TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
+ .AsDictionary("foo-", "System.String"),
+ });
+
+ private static readonly TagHelperDescriptor IntIndexerTagHelper = CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("IntIndexer")
+ .TypeName("System.Collections.Generic.Dictionary<System.String, System.Int32>")
+ .AsDictionary("foo-", "System.Int32"),
+ });
+
+ private static readonly SourceSpan Span = new SourceSpan("test.cshtml", 15, 2, 5, 2);
+
+ [Fact]
+ public void WriteTagHelperBody_DesignTime_WritesChildren()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperBodyIntermediateNode()
+ {
+ Children =
+ {
+ new CSharpExpressionIntermediateNode(),
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperBody(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Render Children
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperBody_Runtime_RendersCorrectly_UsesTagNameAndModeFromContext()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperBodyIntermediateNode()
+ {
+ Children =
+ {
+ new CSharpExpressionIntermediateNode(),
+ },
+ TagMode = TagMode.SelfClosing,
+ TagName = "p",
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperBody(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__tagHelperExecutionContext = __tagHelperScopeManager.Begin(""p"", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, ""test"", async() => {
+ Render Children
+}
+);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperCreate_DesignTime_RendersCorrectly_UsesSpecifiedTagHelperType()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperCreateIntermediateNode()
+ {
+ FieldName = "__TestNamespace_MyTagHelper",
+ TypeName = "TestNamespace.MyTagHelper",
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperCreate(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperCreate_Runtime_RendersCorrectly_UsesSpecifiedTagHelperType()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperCreateIntermediateNode()
+ {
+ FieldName = "__TestNamespace_MyTagHelper",
+ TypeName = "TestNamespace.MyTagHelper",
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperCreate(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
+__tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperExecute_DesignTime_WritesNothing()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperExecuteIntermediateNode();
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperExecute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+ @"",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperExecute_Runtime_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperExecuteIntermediateNode();
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperExecute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+if (!__tagHelperExecutionContext.Output.IsContentModified)
+{
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+}
+Write(__tagHelperExecutionContext.Output);
+__tagHelperExecutionContext = __tagHelperScopeManager.End();
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperHtmlAttribute_DesignTime_WritesNothing()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
+ {
+ AttributeName = "name",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ Children =
+ {
+ new HtmlAttributeValueIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.Html, Content = "Blah-" } }
+ },
+ new CSharpCodeAttributeValueIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "\"Foo\"", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperHtmlAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Render Children
+Render Children
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperHtmlAttribute_Runtime_SimpleAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
+ {
+ AttributeName = "name",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ Children =
+ {
+ new HtmlAttributeIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.Html, Content = "\"value\"", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperHtmlAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"BeginWriteTagHelperAttribute();
+Render Children
+__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+__tagHelperExecutionContext.AddHtmlAttribute(""name"", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperHtmlAttribute_Runtime_DynamicAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperHtmlAttributeIntermediateNode()
+ {
+ AttributeName = "name",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ Children =
+ {
+ new HtmlAttributeValueIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.Html, Content = "Blah-" } }
+ },
+ new CSharpCodeAttributeValueIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "\"Foo\"", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperHtmlAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"BeginAddHtmlAttributeValues(__tagHelperExecutionContext, ""name"", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+Render Children
+Render Children
+EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void RenderTagHelperAttributeInline_NonString_StatementInAttribute_Errors()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ IsIndexerNameMatch = false,
+ };
+ var expectedLocation = new SourceSpan(100, 10);
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(expectedLocation);
+
+ // Act
+ extension.RenderTagHelperAttributeInline(context, node, new CSharpCodeIntermediateNode(), expectedLocation);
+
+ // Assert
+ var diagnostic = Assert.Single(context.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void RenderTagHelperAttributeInline_NonStringIndexerMatch_TemplateInAttribute_Errors()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ IsIndexerNameMatch = true,
+ };
+ var expectedLocation = new SourceSpan(100, 10);
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(expectedLocation, "System.Int32");
+
+ // Act
+ extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation);
+
+ // Assert
+ var diagnostic = Assert.Single(context.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void RenderTagHelperAttributeInline_NonString_TemplateInAttribute_Errors()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ IsIndexerNameMatch = false,
+ };
+ var expectedLocation = new SourceSpan(100, 10);
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(
+ expectedLocation,
+ "System.Collections.Generic.Dictionary<System.String, System.Int32>");
+
+ // Act
+ extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation);
+
+ // Assert
+ var diagnostic = Assert.Single(context.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_StringProperty_HtmlContent_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "StringProp",
+ TagHelper = StringPropertyTagHelper,
+ Children =
+ {
+ new HtmlContentIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.Html, Content = "value", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Render Children
+__InputTagHelper.StringProp = ""value"";
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact] // We don't actually assign the expression result at design time, we just use string.Empty as a placeholder.
+ public void WriteTagHelperProperty_DesignTime_StringProperty_NonHtmlContent_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "StringProp",
+ TagHelper = StringPropertyTagHelper,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "\"3+5\"", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"Render Children
+__InputTagHelper.StringProp = string.Empty;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_NonStringProperty_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 3 ""test.cshtml""
+__InputTagHelper.IntProp = 32;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ // If a value is bound to multiple tag helpers, we want to make sure to only render the first
+ // occurrence of the expression due to side-effects.
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_NonStringProperty_SecondUseOfAttribute()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node1 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ // We only look at the attribute name here.
+ AttributeName = "bound",
+ FieldName = "__OtherTagHelper",
+ PropertyName = "IntProp",
+ };
+ var node2 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Source = Span,
+ };
+ tagHelperNode.Children.Add(node1);
+ tagHelperNode.Children.Add(node2);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node2);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__InputTagHelper.IntProp = __OtherTagHelper.IntProp;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_NonStringProperty_RendersCorrectly_WithoutLocation()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__InputTagHelper.IntProp = 32;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_NonStringIndexer_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 3 ""test.cshtml""
+__InputTagHelper.IntIndexer[""bound""] = 32;
+
+#line default
+#line hidden
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_DesignTime_NonStringIndexer_RendersCorrectly_WithoutLocation()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__InputTagHelper.IntIndexer[""bound""] = 32;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_StringProperty_HtmlContent_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = StringPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "StringProp",
+ TagHelper = StringPropertyTagHelper,
+ Children =
+ {
+ new HtmlContentIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.Html, Content = "\"value\"", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+
+ // The attribute value is not rendered inline because we are not using the preallocated writer.
+ Assert.Equal(
+@"BeginWriteTagHelperAttribute();
+Render Children
+__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+__InputTagHelper.StringProp = __tagHelperStringValueBuffer;
+__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.StringProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_NonStringProperty_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ },
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 3 ""test.cshtml""
+__InputTagHelper.IntProp = 32;
+
+#line default
+#line hidden
+__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.IntProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ // If a value is bound to multiple tag helpers, we want to make sure to only render the first
+ // occurrence of the expression due to side-effects.
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_NonStringProperty_SecondUseOfAttribute()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node1 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ // We only look at the attribute name here.
+ AttributeName = "bound",
+ FieldName = "__OtherTagHelper",
+ PropertyName = "IntProp",
+ };
+ var node2 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Source = Span,
+ };
+ tagHelperNode.Children.Add(node1);
+ tagHelperNode.Children.Add(node2);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node2);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__InputTagHelper.IntProp = __OtherTagHelper.IntProp;
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_NonStringProperty_RendersCorrectly_WithoutLocation()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = false,
+ PropertyName = "IntProp",
+ TagHelper = IntPropertyTagHelper,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__InputTagHelper.IntProp = 32;
+__tagHelperExecutionContext.AddTagHelperAttribute(""bound"", __InputTagHelper.IntProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_NonStringIndexer_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"if (__InputTagHelper.IntIndexer == null)
+{
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""IntIndexer""));
+}
+#line 3 ""test.cshtml""
+__InputTagHelper.IntIndexer[""bound""] = 32;
+
+#line default
+#line hidden
+__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact] // We should only emit the validation code for the first use of an indexer property.
+ public void WriteTagHelperProperty_Runtime_NonStringIndexer_MultipleValues()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node1 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-first",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "17", } },
+ }
+ }
+ };
+ var node2 = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Source = Span,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node1);
+ tagHelperNode.Children.Add(node2);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node2);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line 3 ""test.cshtml""
+__InputTagHelper.IntIndexer[""bound""] = 32;
+
+#line default
+#line hidden
+__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_Runtime_NonStringIndexer_RendersCorrectly_WithoutLocation()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new DefaultTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "foo-bound",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(),
+ FieldName = "__InputTagHelper",
+ IsIndexerNameMatch = true,
+ PropertyName = "IntIndexer",
+ TagHelper = IntIndexerTagHelper,
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ {
+ Children = { new IntermediateToken { Kind = TokenKind.CSharp, Content = "32", } },
+ }
+ }
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"if (__InputTagHelper.IntIndexer == null)
+{
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""foo-bound"", ""InputTagHelper"", ""IntIndexer""));
+}
+__InputTagHelper.IntIndexer[""bound""] = 32;
+__tagHelperExecutionContext.AddTagHelperAttribute(""foo-bound"", __InputTagHelper.IntIndexer[""bound""], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperRuntime_DesignTime_WritesNothing()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DefaultTagHelperRuntimeIntermediateNode();
+
+ // Act
+ extension.WriteTagHelperRuntime(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+ @"",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperRuntime_Runtime_DeclaresRequiredFields()
+ {
+ // Arrange
+ var extension = new DefaultTagHelperTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new DefaultTagHelperRuntimeIntermediateNode();
+
+ // Act
+ extension.WriteTagHelperRuntime(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#line hidden
+#pragma warning disable 0169
+private string __tagHelperStringValueBuffer;
+#pragma warning restore 0169
+private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+{
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+}
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ private static void Push(CodeRenderingContext context, TagHelperIntermediateNode node)
+ {
+ ((DefaultCodeRenderingContext)context).AncestorsInternal.Push(node);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument)
+ {
+ var projectEngine = RazorProjectEngine.Create();
+
+ return Lower(codeDocument, projectEngine);
+ }
+
+ private static DocumentIntermediateNode LowerDesignTime(RazorCodeDocument codeDocument)
+ {
+ var projectEngine = RazorProjectEngine.Create(b =>
+ {
+ b.Features.Add(new DesignTimeOptionsFeature(designTime: true));
+ });
+
+ return Lower(codeDocument, projectEngine);
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine engine)
+ {
+ for (var i = 0; i < engine.Phases.Count; i++)
+ {
+ var phase = engine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorIntermediateNodeLoweringPhase)
+ {
+ break;
+ }
+ }
+
+ var irDocument = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(irDocument);
+
+ return irDocument;
+ }
+
+ private static TagHelperDescriptor CreateTagHelperDescriptor(
+ string tagName,
+ string typeName,
+ string assemblyName,
+ IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
+ {
+ var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
+ builder.TypeName(typeName);
+
+ if (attributes != null)
+ {
+ foreach (var attributeBuilder in attributes)
+ {
+ builder.BindAttribute(attributeBuilder);
+ }
+ }
+
+ builder.TagMatchingRule(ruleBuilder => ruleBuilder.RequireTagName(tagName));
+
+ var descriptor = builder.Build();
+
+ return descriptor;
+ }
+
+ private class DesignTimeOptionsFeature : IConfigureRazorParserOptionsFeature, IConfigureRazorCodeGenerationOptionsFeature
+ {
+ private bool _designTime;
+
+ public DesignTimeOptionsFeature(bool designTime)
+ {
+ _designTime = designTime;
+ }
+
+ public int Order { get; }
+
+ public RazorEngine Engine { get; set; }
+
+ public void Configure(RazorParserOptionsBuilder options)
+ {
+ options.SetDesignTime(_designTime);
+ }
+
+ public void Configure(RazorCodeGenerationOptionsBuilder options)
+ {
+ options.SetDesignTime(_designTime);
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DesignTimeDirectiveTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DesignTimeDirectiveTargetExtensionTest.cs
new file mode 100644
index 0000000000..e06f7a5dcc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DesignTimeDirectiveTargetExtensionTest.cs
@@ -0,0 +1,217 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class DesignTimeDirectiveTargetExtensionTest
+ {
+ [Fact]
+ public void WriteDesignTimeDirective_NoChildren_WritesEmptyMethod_WithPragma()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDesignTimeDirective_WithTypeToken_WritesLambda()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+ var token = new DirectiveTokenIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
+ Content = "System.String",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Type),
+ };
+ node.Children.Add(token);
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+((System.Action)(() => {
+System.String __typeHelper = default(System.String);
+}
+))();
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDesignTimeDirective_WithNamespaceToken_WritesLambda()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+ var token = new DirectiveTokenIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
+ Content = "System.Collections.Generic",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Namespace),
+ };
+ node.Children.Add(token);
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+((System.Action)(() => {
+global::System.Object __typeHelper = nameof(System.Collections.Generic);
+}
+))();
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDesignTimeDirective_WithMemberToken_WritesLambda()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+ var token = new DirectiveTokenIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
+ Content = "Foo",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Member),
+ };
+ node.Children.Add(token);
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+((System.Action)(() => {
+global::System.Object Foo = null;
+}
+))();
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDesignTimeDirective_WithStringToken_WritesLambda()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+ var token = new DirectiveTokenIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
+ Content = "Value",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
+ };
+ var tokenWithQuotedContent = new DirectiveTokenIntermediateNode()
+ {
+ Source = new SourceSpan("test.cshtml", 0, 0, 0, 5),
+ Content = "\"Value\"",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
+ };
+ node.Children.Add(token);
+ node.Children.Add(tokenWithQuotedContent);
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+((System.Action)(() => {
+global::System.Object __typeHelper = ""Value"";
+}
+))();
+((System.Action)(() => {
+global::System.Object __typeHelper = ""Value"";
+}
+))();
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteDesignTimeDirective_ChildrenWithNoSource_WritesEmptyMethod_WithPragma()
+ {
+ // Arrange
+ var extension = new DesignTimeDirectiveTargetExtension();
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ var node = new DesignTimeDirectiveIntermediateNode();
+ var token = new DirectiveTokenIntermediateNode()
+ {
+ Content = "Value",
+ DirectiveToken = DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.String),
+ };
+ node.Children.Add(token);
+
+ // Act
+ extension.WriteDesignTimeDirective(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"#pragma warning disable 219
+private void __RazorDirectiveTokenHelpers__() {
+}
+#pragma warning restore 219
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/FunctionsDirectivePassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/FunctionsDirectivePassTest.cs
new file mode 100644
index 0000000000..78e27786f4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/FunctionsDirectivePassTest.cs
@@ -0,0 +1,104 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class FunctionsDirectivePassTest
+ {
+ [Fact]
+ public void Execute_SkipsDocumentWithNoClassNode()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var pass = new FunctionsDirectivePass()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("@functions { var value = true; }");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode();
+ irDocument.Children.Add(new DirectiveIntermediateNode() { Directive = FunctionsDirective.Directive, });
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<DirectiveIntermediateNode>(node));
+ }
+
+ [Fact]
+ public void Execute_AddsStatementsToClassLevel()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var pass = new FunctionsDirectivePass()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("@functions { var value = true; }");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = Lower(codeDocument, projectEngine);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+
+ var @namespace = irDocument.Children[0];
+ Children(
+ @namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+
+ var @class = @namespace.Children[0];
+ Children(
+ @class,
+ node => Assert.IsType<MethodDeclarationIntermediateNode>(node),
+ node => CSharpCode(" var value = true; ", node));
+
+ var method = @class.Children[0];
+ Children(
+ method,
+ node => Assert.IsType<DirectiveIntermediateNode>(node));
+ }
+
+ private static RazorProjectEngine CreateProjectEngine()
+ {
+ return RazorProjectEngine.Create(b =>
+ {
+ FunctionsDirective.Register(b);
+ });
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
+ {
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorDocumentClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ var irDocument = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(irDocument);
+
+ return irDocument;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/InheritsDirectivePassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/InheritsDirectivePassTest.cs
new file mode 100644
index 0000000000..86603155dd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/InheritsDirectivePassTest.cs
@@ -0,0 +1,97 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class InheritsDirectivePassTest
+ {
+ [Fact]
+ public void Execute_SkipsDocumentWithNoClassNode()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new InheritsDirectivePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("@inherits Hello<World[]>");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode();
+ irDocument.Children.Add(new DirectiveIntermediateNode() { Directive = FunctionsDirective.Directive, });
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<DirectiveIntermediateNode>(node));
+ }
+
+ [Fact]
+ public void Execute_Inherits_SetsClassDeclarationBaseType()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new InheritsDirectivePass()
+ {
+ Engine = engine,
+ };
+
+ var content = "@inherits Hello<World[]>";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = Lower(codeDocument, engine);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+
+ var @namespace = irDocument.Children[0];
+ Children(
+ @namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+
+ var @class = (ClassDeclarationIntermediateNode)@namespace.Children[0];
+ Assert.Equal("Hello<World[]>", @class.BaseType);
+ }
+
+ private static RazorEngine CreateEngine()
+ {
+ return RazorProjectEngine.Create(b =>
+ {
+ InheritsDirective.Register(b);
+ }).Engine;
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorEngine engine)
+ {
+ for (var i = 0; i < engine.Phases.Count; i++)
+ {
+ var phase = engine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorDocumentClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ var irDocument = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(irDocument);
+
+ return irDocument;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributePassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributePassTest.cs
new file mode 100644
index 0000000000..f5898dce90
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributePassTest.cs
@@ -0,0 +1,362 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class MetadataAttributePassTest
+ {
+ [Fact]
+ public void Execute_NullCodeGenerationOptions_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode();
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ NoChildren(irDocument);
+ }
+
+ [Fact]
+ public void Execute_SuppressMetadataAttributes_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ Options = RazorCodeGenerationOptions.Create(o =>
+ {
+ o.SuppressMetadataAttributes = true;
+ }),
+ };
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ NoChildren(irDocument);
+ }
+
+ [Fact]
+ public void Execute_NoNamespaceSet_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Options = RazorCodeGenerationOptions.Create((o) => { }),
+ };
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ ClassName = "Test",
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ SingleChild<NamespaceDeclarationIntermediateNode>(irDocument);
+ }
+
+ [Fact]
+ public void Execute_NoClassNameSet_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Options = RazorCodeGenerationOptions.Create((o) => { }),
+ };
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ Content = "Some.Namespace"
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ SingleChild<NamespaceDeclarationIntermediateNode>(irDocument);
+ }
+
+ [Fact]
+ public void Execute_NoDocumentKind_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode();
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ Content = "Some.Namespace"
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ ClassName = "Test",
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ SingleChild<NamespaceDeclarationIntermediateNode>(irDocument);
+ }
+
+ [Fact]
+ public void Execute_NoIdentifier_Noops()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("", new RazorSourceDocumentProperties(null, null));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Options = RazorCodeGenerationOptions.Create((o) => { }),
+ };
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ Content = "Some.Namespace"
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ ClassName = "Test",
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ SingleChild<NamespaceDeclarationIntermediateNode>(irDocument);
+ }
+
+ [Fact]
+ public void Execute_HasRequiredInfo_AddsItemAndSourceChecksum()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("", new RazorSourceDocumentProperties(null, "Foo\\Bar.cshtml"));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Options = RazorCodeGenerationOptions.Create((o) => { }),
+ };
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ Content = "Some.Namespace"
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ ClassName = "Test",
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Assert.Equal(2, irDocument.Children.Count);
+
+ var item = Assert.IsType<RazorCompiledItemAttributeIntermediateNode>(irDocument.Children[0]);
+ Assert.Equal("/Foo/Bar.cshtml", item.Identifier);
+ Assert.Equal("test", item.Kind);
+ Assert.Equal("Some.Namespace.Test", item.TypeName);
+
+ Assert.Equal(2, @namespace.Children.Count);
+ var checksum = Assert.IsType<RazorSourceChecksumAttributeIntermediateNode>(@namespace.Children[0]);
+ Assert.NotNull(checksum.Checksum); // Not verifying the checksum here
+ Assert.Equal("SHA1", checksum.ChecksumAlgorithm);
+ Assert.Equal("/Foo/Bar.cshtml", checksum.Identifier);
+ }
+
+ [Fact]
+ public void Execute_HasRequiredInfo_AndImport_AddsItemAndSourceChecksum()
+ {
+ // Arrange
+ var engine = CreateEngine();
+ var pass = new MetadataAttributePass()
+ {
+ Engine = engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("", new RazorSourceDocumentProperties(null, "Foo\\Bar.cshtml"));
+ var import = TestRazorSourceDocument.Create("@using System", new RazorSourceDocumentProperties(null, "Foo\\Import.cshtml"));
+ var codeDocument = RazorCodeDocument.Create(sourceDocument, new[] { import, });
+
+ var irDocument = new DocumentIntermediateNode()
+ {
+ DocumentKind = "test",
+ Options = RazorCodeGenerationOptions.Create((o) => { }),
+ };
+ var builder = IntermediateNodeBuilder.Create(irDocument);
+ var @namespace = new NamespaceDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace,
+ },
+ Content = "Some.Namespace"
+ };
+ builder.Push(@namespace);
+ var @class = new ClassDeclarationIntermediateNode
+ {
+ Annotations =
+ {
+ [CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass,
+ },
+ ClassName = "Test",
+ };
+ builder.Add(@class);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Assert.Equal(2, irDocument.Children.Count);
+
+ var item = Assert.IsType<RazorCompiledItemAttributeIntermediateNode>(irDocument.Children[0]);
+ Assert.Equal("/Foo/Bar.cshtml", item.Identifier);
+ Assert.Equal("test", item.Kind);
+ Assert.Equal("Some.Namespace.Test", item.TypeName);
+
+ Assert.Equal(3, @namespace.Children.Count);
+ var checksum = Assert.IsType<RazorSourceChecksumAttributeIntermediateNode>(@namespace.Children[0]);
+ Assert.NotNull(checksum.Checksum); // Not verifying the checksum here
+ Assert.Equal("SHA1", checksum.ChecksumAlgorithm);
+ Assert.Equal("/Foo/Bar.cshtml", checksum.Identifier);
+
+ checksum = Assert.IsType<RazorSourceChecksumAttributeIntermediateNode>(@namespace.Children[1]);
+ Assert.NotNull(checksum.Checksum); // Not verifying the checksum here
+ Assert.Equal("SHA1", checksum.ChecksumAlgorithm);
+ Assert.Equal("/Foo/Import.cshtml", checksum.Identifier);
+ }
+
+ private static RazorEngine CreateEngine()
+ {
+ return RazorProjectEngine.Create(b =>
+ {
+ b.Features.Add(new DefaultMetadataIdentifierFeature());
+ }).Engine;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributeTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributeTargetExtensionTest.cs
new file mode 100644
index 0000000000..faeaf4d662
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/MetadataAttributeTargetExtensionTest.cs
@@ -0,0 +1,123 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class MetadataAttributeTargetExtensionTest
+ {
+ [Fact]
+ public void WriteRazorCompiledItemAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new MetadataAttributeTargetExtension()
+ {
+ CompiledItemAttributeName = "global::TestItem",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new RazorCompiledItemAttributeIntermediateNode()
+ {
+ TypeName = "Foo.Bar",
+ Kind = "test",
+ Identifier = "Foo/Bar",
+ };
+
+ // Act
+ extension.WriteRazorCompiledItemAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"[assembly: global::TestItem(typeof(Foo.Bar), @""test"", @""Foo/Bar"")]
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteRazorSourceChecksumAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new MetadataAttributeTargetExtension()
+ {
+ SourceChecksumAttributeName = "global::TestChecksum",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new RazorSourceChecksumAttributeIntermediateNode()
+ {
+ ChecksumAlgorithm = "SHA1",
+ Checksum = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t', },
+ Identifier = "Foo/Bar",
+ };
+
+ // Act
+ extension.WriteRazorSourceChecksumAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"[global::TestChecksum(@""SHA1"", @""74657374"", @""Foo/Bar"")]
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteRazorCompiledItemAttributeMetadata_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new MetadataAttributeTargetExtension()
+ {
+ CompiledItemMetadataAttributeName = "global::TestItemMetadata",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new RazorCompiledItemMetadataAttributeIntermediateNode
+ {
+ Key = "key",
+ Value = "value",
+ };
+
+ // Act
+ extension.WriteRazorCompiledItemMetadataAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode().Trim();
+ Assert.Equal(
+"[global::TestItemMetadata(\"key\", \"value\")]",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteRazorCompiledItemAttributeMetadata_EscapesKeysAndValuesCorrectly()
+ {
+ // Arrange
+ var extension = new MetadataAttributeTargetExtension()
+ {
+ CompiledItemMetadataAttributeName = "global::TestItemMetadata",
+ };
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new RazorCompiledItemMetadataAttributeIntermediateNode
+ {
+ Key = "\"test\" key",
+ Value = @"""test"" value",
+ };
+
+ // Act
+ extension.WriteRazorCompiledItemMetadataAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode().Trim();
+ Assert.Equal(
+"[global::TestItemMetadata(\"\\\"test\\\" key\", \"\\\"test\\\" value\")]",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/PreallocatedAttributeTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/PreallocatedAttributeTargetExtensionTest.cs
new file mode 100644
index 0000000000..da2f960847
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/PreallocatedAttributeTargetExtensionTest.cs
@@ -0,0 +1,276 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class PreallocatedAttributeTargetExtensionTest
+ {
+ [Fact]
+ public void WriteTagHelperHtmlAttributeValue_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode()
+ {
+ AttributeName = "Foo",
+ Value = "Bar",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ VariableName = "MyProp"
+ };
+
+ // Act
+ extension.WriteTagHelperHtmlAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute MyProp = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"", new global::Microsoft.AspNetCore.Html.HtmlString(""Bar""), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperHtmlAttributeValue_Minimized_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new PreallocatedTagHelperHtmlAttributeValueIntermediateNode()
+ {
+ AttributeName = "Foo",
+ Value = "Bar",
+ AttributeStructure = AttributeStructure.Minimized,
+ VariableName = "_tagHelper1"
+ };
+
+ // Act
+ extension.WriteTagHelperHtmlAttributeValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute _tagHelper1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"");
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperHtmlAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new PreallocatedTagHelperHtmlAttributeIntermediateNode()
+ {
+ VariableName = "_tagHelper1"
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperHtmlAttribute(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__tagHelperExecutionContext.AddHtmlAttribute(_tagHelper1);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperPropertyValue_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var node = new PreallocatedTagHelperPropertyValueIntermediateNode()
+ {
+ AttributeName = "Foo",
+ Value = "Bar",
+ AttributeStructure = AttributeStructure.DoubleQuotes,
+ VariableName = "_tagHelper1",
+ };
+
+ // Act
+ extension.WriteTagHelperPropertyValue(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute _tagHelper1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute(""Foo"", ""Bar"", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteTagHelperProperty_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
+ tagHelperBuilder.TypeName("FooTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("Foo")
+ .TypeName("System.String")
+ .PropertyName("FooProp");
+
+ var descriptor = builder.Build();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new PreallocatedTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = descriptor.Name,
+ BoundAttribute = descriptor,
+ FieldName = "__FooTagHelper",
+ PropertyName = "FooProp",
+ VariableName = "_tagHelper1",
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__FooTagHelper.FooProp = (string)_tagHelper1.Value;
+__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_RendersCorrectly()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
+ tagHelperBuilder.TypeName("FooTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("Foo")
+ .TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
+ .AsDictionaryAttribute("pre-", "System.String")
+ .PropertyName("FooProp");
+
+ var descriptor = builder.Build();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node = new PreallocatedTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "pre-Foo",
+ FieldName = "__FooTagHelper",
+ VariableName = "_tagHelper1",
+ BoundAttribute = descriptor,
+ IsIndexerNameMatch = true,
+ PropertyName = "FooProp",
+ TagHelper = tagHelperBuilder.Build(),
+ };
+ tagHelperNode.Children.Add(node);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"if (__FooTagHelper.FooProp == null)
+{
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""pre-Foo"", ""FooTagHelper"", ""FooProp""));
+}
+__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
+__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ [Fact]
+ public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_MultipleValues()
+ {
+ // Arrange
+ var extension = new PreallocatedAttributeTargetExtension();
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ var tagHelperBuilder = new DefaultTagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
+ tagHelperBuilder.TypeName("FooTagHelper");
+
+ var builder = new DefaultBoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
+ builder
+ .Name("Foo")
+ .TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
+ .AsDictionaryAttribute("pre-", "System.String")
+ .PropertyName("FooProp");
+
+ var boundAttribute = builder.Build();
+ var tagHelper = tagHelperBuilder.Build();
+
+ var tagHelperNode = new TagHelperIntermediateNode();
+ var node1 = new PreallocatedTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "pre-Bar",
+ FieldName = "__FooTagHelper",
+ VariableName = "_tagHelper0s",
+ BoundAttribute = boundAttribute,
+ IsIndexerNameMatch = true,
+ PropertyName = "FooProp",
+ TagHelper = tagHelper,
+ };
+ var node2 = new PreallocatedTagHelperPropertyIntermediateNode()
+ {
+ AttributeName = "pre-Foo",
+ FieldName = "__FooTagHelper",
+ VariableName = "_tagHelper1",
+ BoundAttribute = boundAttribute,
+ IsIndexerNameMatch = true,
+ PropertyName = "FooProp",
+ TagHelper = tagHelper,
+ };
+ tagHelperNode.Children.Add(node1);
+ tagHelperNode.Children.Add(node2);
+ Push(context, tagHelperNode);
+
+ // Act
+ extension.WriteTagHelperProperty(context, node2);
+
+ // Assert
+ var csharp = context.CodeWriter.GenerateCode();
+ Assert.Equal(
+@"__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
+__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
+",
+ csharp,
+ ignoreLineEndingDifferences: true);
+ }
+
+ private static void Push(CodeRenderingContext context, TagHelperIntermediateNode node)
+ {
+ ((DefaultCodeRenderingContext)context).AncestorsInternal.Push(node);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionDirectivePassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionDirectivePassTest.cs
new file mode 100644
index 0000000000..a2f747e7a9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionDirectivePassTest.cs
@@ -0,0 +1,106 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+using static Microsoft.AspNetCore.Razor.Language.Intermediate.IntermediateNodeAssert;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class SectionDirectivePassTest
+ {
+ [Fact]
+ public void Execute_SkipsDocumentWithNoClassNode()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var pass = new SectionDirectivePass()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var sourceDocument = TestRazorSourceDocument.Create("@section Header { <p>Hello World</p> }");
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = new DocumentIntermediateNode();
+ irDocument.Children.Add(new DirectiveIntermediateNode() { Directive = SectionDirective.Directive, });
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<DirectiveIntermediateNode>(node));
+ }
+
+ [Fact]
+ public void Execute_WrapsStatementInSectionNode()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var pass = new SectionDirectivePass()
+ {
+ Engine = projectEngine.Engine,
+ };
+
+ var content = "@section Header { <p>Hello World</p> }";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ var irDocument = Lower(codeDocument, projectEngine);
+
+ // Act
+ pass.Execute(codeDocument, irDocument);
+
+ // Assert
+ Children(
+ irDocument,
+ node => Assert.IsType<NamespaceDeclarationIntermediateNode>(node));
+
+ var @namespace = irDocument.Children[0];
+ Children(
+ @namespace,
+ node => Assert.IsType<ClassDeclarationIntermediateNode>(node));
+
+ var @class = @namespace.Children[0];
+ var method = SingleChild<MethodDeclarationIntermediateNode>(@class);
+
+ Children(
+ method,
+ node => Assert.IsType<DirectiveIntermediateNode>(node),
+ node => Assert.IsType<SectionIntermediateNode>(node));
+
+ var section = method.Children[1] as SectionIntermediateNode;
+ Assert.Equal("Header", section.SectionName);
+ Children(section, c => Html(" <p>Hello World</p> ", c));
+ }
+
+ private static RazorProjectEngine CreateProjectEngine()
+ {
+ return RazorProjectEngine.Create(b =>
+ {
+ SectionDirective.Register(b);
+ });
+ }
+
+ private static DocumentIntermediateNode Lower(RazorCodeDocument codeDocument, RazorProjectEngine projectEngine)
+ {
+ for (var i = 0; i < projectEngine.Phases.Count; i++)
+ {
+ var phase = projectEngine.Phases[i];
+ phase.Execute(codeDocument);
+
+ if (phase is IRazorDocumentClassifierPhase)
+ {
+ break;
+ }
+ }
+
+ var irDocument = codeDocument.GetDocumentIntermediateNode();
+ Assert.NotNull(irDocument);
+
+ return irDocument;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionTargetExtensionTest.cs
new file mode 100644
index 0000000000..16288b3117
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/SectionTargetExtensionTest.cs
@@ -0,0 +1,80 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class SectionTargetExtensionTest
+ {
+ [Fact]
+ public void WriteSection_WritesSectionCode()
+ {
+ // Arrange
+ var node = new SectionIntermediateNode()
+ {
+ Children =
+ {
+ new CSharpExpressionIntermediateNode(),
+ },
+ SectionName = "MySection"
+ };
+
+ var extension = new SectionTargetExtension()
+ {
+ SectionMethodName = "CreateSection"
+ };
+
+ var context = TestCodeRenderingContext.CreateRuntime();
+
+ // Act
+ extension.WriteSection(context, node);
+
+ // Assert
+ var expected = @"CreateSection(""MySection"", async() => {
+ Render Children
+}
+);
+";
+
+ var output = context.CodeWriter.GenerateCode();
+ Assert.Equal(expected, output);
+ }
+
+ [Fact]
+ public void WriteSection_WritesSectionCode_DesignTime()
+ {
+ // Arrange
+ var node = new SectionIntermediateNode()
+ {
+ Children =
+ {
+ new CSharpExpressionIntermediateNode(),
+ },
+ SectionName = "MySection"
+ };
+
+ var extension = new SectionTargetExtension()
+ {
+ SectionMethodName = "CreateSection"
+ };
+
+ var context = TestCodeRenderingContext.CreateDesignTime();
+
+ // Act
+ extension.WriteSection(context, node);
+
+ // Assert
+ var expected = @"CreateSection(""MySection"", async(__razor_section_writer) => {
+ Render Children
+}
+);
+";
+
+ var output = context.CodeWriter.GenerateCode();
+ Assert.Equal(expected, output);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs
new file mode 100644
index 0000000000..b24d6f5174
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs
@@ -0,0 +1,51 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Extensions
+{
+ public class TemplateTargetExtensionTest
+ {
+ [Fact]
+ public void WriteTemplate_WritesTemplateCode()
+ {
+ // Arrange
+ var node = new TemplateIntermediateNode()
+ {
+ Children =
+ {
+ new CSharpExpressionIntermediateNode()
+ }
+ };
+ var extension = new TemplateTargetExtension()
+ {
+ TemplateTypeName = "global::TestTemplate"
+ };
+
+ var nodeWriter = new RuntimeNodeWriter()
+ {
+ PushWriterMethod = "TestPushWriter",
+ PopWriterMethod = "TestPopWriter"
+ };
+
+ var context = TestCodeRenderingContext.CreateRuntime(nodeWriter: nodeWriter);
+
+ // Act
+ extension.WriteTemplate(context, node);
+
+ // Assert
+ var expected = @"item => new global::TestTemplate(async(__razor_template_writer) => {
+ TestPushWriter(__razor_template_writer);
+ Render Children
+ TestPopWriter();
+}
+)";
+
+ var output = context.CodeWriter.GenerateCode();
+ Assert.Equal(expected, output);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlConventionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlConventionsTest.cs
new file mode 100644
index 0000000000..e1020bb81c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlConventionsTest.cs
@@ -0,0 +1,39 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class HtmlConventionsTest
+ {
+ public static TheoryData HtmlConversionData
+ {
+ get
+ {
+ return new TheoryData<string, string>
+ {
+ { "SomeThing", "some-thing" },
+ { "someOtherThing", "some-other-thing" },
+ { "capsONInside", "caps-on-inside" },
+ { "CAPSOnOUTSIDE", "caps-on-outside" },
+ { "ALLCAPS", "allcaps" },
+ { "One1Two2Three3", "one1-two2-three3" },
+ { "ONE1TWO2THREE3", "one1two2three3" },
+ { "First_Second_ThirdHi", "first_second_third-hi" }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(HtmlConversionData))]
+ public void ToHtmlCase_ReturnsExpectedConversions(string input, string expectedOutput)
+ {
+ // Arrange, Act
+ var output = HtmlConventions.ToHtmlCase(input);
+
+ // Assert
+ Assert.Equal(output, expectedOutput);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlNodeOptimizationPassTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlNodeOptimizationPassTest.cs
new file mode 100644
index 0000000000..4ece47b0cd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/HtmlNodeOptimizationPassTest.cs
@@ -0,0 +1,53 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class HtmlNodeOptimizationPassTest
+ {
+ [Fact]
+ public void Execute_CollapsesConditionalAttributes()
+ {
+ // Assert
+ var content = "<input value='hello world' />";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ var pass = new HtmlNodeOptimizationPass();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ // Act
+ var outputTree = pass.Execute(codeDocument, originalTree);
+
+ // Assert
+ var tag = Assert.Single(outputTree.Root.Children);
+ var tagBlock = Assert.IsType<Block>(tag);
+ Assert.Equal(BlockKindInternal.Tag, tagBlock.Type);
+ Assert.Equal(3, tagBlock.Children.Count);
+ Assert.IsType<Span>(tagBlock.Children[1]);
+ }
+
+ [Fact]
+ public void Execute_RewritesWhitespace()
+ {
+ // Assert
+ var content = Environment.NewLine + " @true";
+ var sourceDocument = TestRazorSourceDocument.Create(content);
+ var originalTree = RazorSyntaxTree.Parse(sourceDocument);
+ var pass = new HtmlNodeOptimizationPass();
+ var codeDocument = RazorCodeDocument.Create(sourceDocument);
+
+ // Act
+ var outputTree = pass.Execute(codeDocument, originalTree);
+
+ // Assert
+ Assert.Equal(4, outputTree.Root.Children.Count);
+ var whitespace = Assert.IsType<Span>(outputTree.Root.Children[1]);
+ Assert.True(whitespace.Content.All(char.IsWhiteSpace));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/BasicIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/BasicIntegrationTest.cs
new file mode 100644
index 0000000000..4f9facbdfd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/BasicIntegrationTest.cs
@@ -0,0 +1,117 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class BasicIntegrationTest : IntegrationTestBase
+ {
+ [Fact]
+ public void Empty()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void HelloWorld()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void CustomDirective()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine(b =>
+ {
+ b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void BuildEngine_CallProcess()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = new TestRazorProjectItem("Index.cshtml");
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ Assert.NotNull(codeDocument.GetSyntaxTree());
+ Assert.NotNull(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void CSharpDocument_Runtime_PreservesParserErrors()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = new TestRazorProjectItem("test.cshtml")
+ {
+ Content = "@!!!"
+ };
+
+ var expected = RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1),
+ "!");
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ var csharpDocument = codeDocument.GetCSharpDocument();
+ var error = Assert.Single(csharpDocument.Diagnostics);
+ Assert.Equal(expected, error);
+ }
+
+ [Fact]
+ public void CSharpDocument_DesignTime_PreservesParserErrors()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = new TestRazorProjectItem("test.cshtml")
+ {
+ Content = "@{"
+ };
+
+ var expected = RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation("test.cshtml", 1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{");
+
+ // Act
+ var codeDocument = projectEngine.ProcessDesignTime(projectItem);
+
+ // Assert
+ var csharpDocument = codeDocument.GetCSharpDocument();
+ var error = Assert.Single(csharpDocument.Diagnostics);
+ Assert.Equal(expected, error);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/CodeGenerationIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/CodeGenerationIntegrationTest.cs
new file mode 100644
index 0000000000..e40989bbb3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/CodeGenerationIntegrationTest.cs
@@ -0,0 +1,987 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class CodeGenerationIntegrationTest : IntegrationTestBase
+ {
+ #region Runtime
+ [Fact]
+ public void IncompleteDirectives_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void CSharp7_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void BasicImports_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void UnfinishedExpressionInCode_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Templates_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void StringLiterals_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void SimpleUnspacedIf_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Sections_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void RazorComments_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ParserError_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void OpenedIf_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void NullConditionalExpressions_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void NoLinePragmas_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void NestedCSharp_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void NestedCodeBlocks_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void MarkupInCodeBlock_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Instrumented_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void InlineBlocks_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Inherits_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Usings_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ImplicitExpressionAtEOF_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ImplicitExpression_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void HtmlCommentWithQuote_Double_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void HtmlCommentWithQuote_Single_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void HiddenSpansInCode_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void FunctionsBlock_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void FunctionsBlockMinimal_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ExpressionsInCode_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpressionWithMarkup_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpressionAtEOF_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpression_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void EmptyImplicitExpressionInCode_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void EmptyImplicitExpression_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void EmptyExplicitExpression_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void EmptyCodeBlock_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void ConditionalAttributes_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlockWithTextElement_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlockAtEOF_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlock_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Blocks_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void Await_Runtime()
+ {
+ RunTimeTest();
+ }
+
+ [Fact]
+ public void SimpleTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithBoundAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithPrefix_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void NestedTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SingleTagHelper_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SingleTagHelperWithNewlineBeforeAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithWeirdlySpacedAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void IncompleteTagHelper_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void BasicTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void BasicTagHelpers_Prefixed_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void BasicTagHelpers_RemoveTagHelper_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void CssSelectorTagHelperAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.CssSelectorTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void ComplexTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EmptyAttributeTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EscapedTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DuplicateTargetTagHelper_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DuplicateTargetTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void AttributeTargetingTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.AttributeTargetingTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void PrefixedAttributeTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.PrefixedAttributeTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DuplicateAttributeTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DynamicAttributeTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DynamicAttributeTagHelpers_Descriptors);
+ }
+
+ [Fact]
+ public void TransitionsInTagHelperAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void MinimizedTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.MinimizedTagHelpers_Descriptors);
+ }
+
+ [Fact]
+ public void NestedScriptTagTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SymbolBoundAttributes_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SymbolBoundTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EnumTagHelpers_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.EnumTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersInSection_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.TagHelpersInSectionDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithTemplate_Runtime()
+ {
+ // Arrange, Act & Assert
+ RunRuntimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+ #endregion
+
+ #region DesignTime
+ [Fact]
+ public void IncompleteDirectives_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void CSharp7_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void BasicImports_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void UnfinishedExpressionInCode_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Templates_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void StringLiterals_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void SimpleUnspacedIf_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Sections_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void RazorComments_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ParserError_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void OpenedIf_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void NullConditionalExpressions_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void NoLinePragmas_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void NestedCSharp_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void NestedCodeBlocks_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void MarkupInCodeBlock_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Instrumented_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void InlineBlocks_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Inherits_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Usings_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ImplicitExpressionAtEOF_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ImplicitExpression_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void HtmlCommentWithQuote_Double_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void HtmlCommentWithQuote_Single_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void HiddenSpansInCode_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void FunctionsBlock_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void FunctionsBlockMinimal_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ExpressionsInCode_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpressionWithMarkup_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpressionAtEOF_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ExplicitExpression_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void EmptyImplicitExpressionInCode_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void EmptyImplicitExpression_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void EmptyExplicitExpression_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void EmptyCodeBlock_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void DesignTime_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void ConditionalAttributes_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlockWithTextElement_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlockAtEOF_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void CodeBlock_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Blocks_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void Await_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_DesignTime()
+ {
+ DesignTimeTest();
+ }
+
+ [Fact]
+ public void SimpleTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithBoundAttributes_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithPrefix_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void NestedTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SingleTagHelper_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SingleTagHelperWithNewlineBeforeAttributes_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithWeirdlySpacedAttributes_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void IncompleteTagHelper_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void BasicTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void BasicTagHelpers_Prefixed_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void ComplexTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EmptyAttributeTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EscapedTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DuplicateTargetTagHelper_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DuplicateTargetTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void AttributeTargetingTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.AttributeTargetingTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void PrefixedAttributeTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.PrefixedAttributeTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DuplicateAttributeTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void DynamicAttributeTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DynamicAttributeTagHelpers_Descriptors);
+ }
+
+ [Fact]
+ public void TransitionsInTagHelperAttributes_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void MinimizedTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.MinimizedTagHelpers_Descriptors);
+ }
+
+ [Fact]
+ public void NestedScriptTagTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.DefaultPAndInputTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void SymbolBoundAttributes_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SymbolBoundTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void EnumTagHelpers_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.EnumTagHelperDescriptors);
+ }
+
+ [Fact]
+ public void TagHelpersWithTemplate_DesignTime()
+ {
+ // Arrange, Act & Assert
+ RunDesignTimeTagHelpersTest(TestTagHelperDescriptors.SimpleTagHelperDescriptors);
+ }
+ #endregion
+
+ private void DesignTimeTest()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine(builder =>
+ {
+ builder.ConfigureDocumentClassifier();
+
+ // Some of these tests use templates
+ builder.AddTargetExtension(new TemplateTargetExtension());
+
+ FunctionsDirective.Register(builder);
+ InheritsDirective.Register(builder);
+ SectionDirective.Register(builder);
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.ProcessDesignTime(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
+ AssertSourceMappingsMatchBaseline(codeDocument);
+ }
+
+ private void RunTimeTest()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine(builder =>
+ {
+ builder.ConfigureDocumentClassifier();
+
+ // Some of these tests use templates
+ builder.AddTargetExtension(new TemplateTargetExtension());
+
+ FunctionsDirective.Register(builder);
+ InheritsDirective.Register(builder);
+ SectionDirective.Register(builder);
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
+ }
+
+ private void RunRuntimeTagHelpersTest(IEnumerable<TagHelperDescriptor> descriptors)
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine(builder =>
+ {
+ builder.ConfigureDocumentClassifier();
+ builder.AddTagHelpers(descriptors);
+
+ // Some of these tests use templates
+ builder.AddTargetExtension(new TemplateTargetExtension());
+
+ FunctionsDirective.Register(builder);
+ InheritsDirective.Register(builder);
+ SectionDirective.Register(builder);
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
+ }
+
+ private void RunDesignTimeTagHelpersTest(IEnumerable<TagHelperDescriptor> descriptors)
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine(builder =>
+ {
+ builder.ConfigureDocumentClassifier();
+ builder.AddTagHelpers(descriptors);
+
+ // Some of these tests use templates
+ builder.AddTargetExtension(new TemplateTargetExtension());
+
+ FunctionsDirective.Register(builder);
+ InheritsDirective.Register(builder);
+ SectionDirective.Register(builder);
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.ProcessDesignTime(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
+ AssertSourceMappingsMatchBaseline(codeDocument);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/ExtensibleDirectiveTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/ExtensibleDirectiveTest.cs
new file mode 100644
index 0000000000..9e722b53b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/ExtensibleDirectiveTest.cs
@@ -0,0 +1,33 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ // Extensible directives only have codegen for design time, so we're only testing that.
+ public class ExtensibleDirectiveTest : IntegrationTestBase
+ {
+ [Fact]
+ public void NamespaceToken()
+ {
+ // Arrange
+ var engine = CreateProjectEngine(builder =>
+ {
+ builder.ConfigureDocumentClassifier();
+
+ builder.AddDirective(DirectiveDescriptor.CreateDirective("custom", DirectiveKind.SingleLine, b => b.AddNamespaceToken()));
+ });
+
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = engine.ProcessDesignTime(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ AssertCSharpDocumentMatchesBaseline(codeDocument.GetCSharpDocument());
+ AssertSourceMappingsMatchBaseline(codeDocument);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/HtmlAttributeIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/HtmlAttributeIntegrationTest.cs
new file mode 100644
index 0000000000..7683ca94ae
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/HtmlAttributeIntegrationTest.cs
@@ -0,0 +1,38 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class HtmlAttributeIntegrationTest : IntegrationTestBase
+ {
+ [Fact]
+ public void HtmlWithDataDashAttribute()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void HtmlWithConditionalAttribute()
+ {
+ // Arrange
+ var projectEngine = CreateProjectEngine();
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs
new file mode 100644
index 0000000000..d028aedd26
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/RazorTemplateEngineIntegrationTest.cs
@@ -0,0 +1,103 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class RazorTemplateEngineIntegrationTest : IntegrationTestBase
+ {
+ [Fact]
+ public void GenerateCodeWithDefaults()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestProjectRoot);
+ var razorEngine = RazorProjectEngine.Create(engine =>
+ {
+ engine.Features.Add(new SuppressChecksumOptionsFeature());
+ }).Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode($"{FileName}.cshtml");
+
+ // Assert
+ AssertCSharpDocumentMatchesBaseline(cSharpDocument);
+ }
+
+ [Fact]
+ public void GenerateCodeWithBaseType()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestProjectRoot);
+ var razorEngine = RazorProjectEngine.Create(engine =>
+ {
+ engine.Features.Add(new SuppressChecksumOptionsFeature());
+
+ engine.SetBaseType("MyBaseType");
+ }).Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode($"{FileName}.cshtml");
+
+ // Assert
+ AssertCSharpDocumentMatchesBaseline(cSharpDocument);
+ }
+
+ [Fact]
+ public void GenerateCodeWithConfigureClass()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestProjectRoot);
+ var razorEngine = RazorProjectEngine.Create(engine =>
+ {
+ engine.Features.Add(new SuppressChecksumOptionsFeature());
+
+ engine.ConfigureClass((document, @class) =>
+ {
+ @class.ClassName = "MyClass";
+
+ @class.Modifiers.Clear();
+ @class.Modifiers.Add("protected");
+ @class.Modifiers.Add("internal");
+ });
+
+ engine.ConfigureClass((document, @class) =>
+ {
+ @class.TypeParameters = new[] { new TypeParameter() { ParameterName = "TValue", }, };
+ @class.Interfaces = new[] { "global::System.IDisposable" };
+ @class.BaseType = "CustomBaseType";
+ });
+ }).Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode($"{FileName}.cshtml");
+
+ // Assert
+ AssertCSharpDocumentMatchesBaseline(cSharpDocument);
+ }
+
+ [Fact]
+ public void GenerateCodeWithSetNamespace()
+ {
+ // Arrange
+ var fileSystem = new DefaultRazorProjectFileSystem(TestProjectRoot);
+ var razorEngine = RazorProjectEngine.Create(engine =>
+ {
+ engine.Features.Add(new SuppressChecksumOptionsFeature());
+
+ engine.SetNamespace("MyApp.Razor.Views");
+ }).Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode($"{FileName}.cshtml");
+
+ // Assert
+ AssertCSharpDocumentMatchesBaseline(cSharpDocument);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TagHelpersIntegrationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TagHelpersIntegrationTest.cs
new file mode 100644
index 0000000000..7d7ce390ec
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TagHelpersIntegrationTest.cs
@@ -0,0 +1,124 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class TagHelpersIntegrationTest : IntegrationTestBase
+ {
+ [Fact]
+ public void SimpleTagHelpers()
+ {
+ // Arrange
+ var descriptors = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly")
+ };
+
+ var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void TagHelpersWithBoundAttributes()
+ {
+ // Arrange
+ var descriptors = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("FooProp")
+ .TypeName("System.String"),
+ })
+ };
+
+ var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ [Fact]
+ public void NestedTagHelpers()
+ {
+ // Arrange
+ var descriptors = new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "p",
+ typeName: "PTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "form",
+ typeName: "FormTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("value")
+ .PropertyName("FooProp")
+ .TypeName("System.String"),
+ })
+ };
+
+ var projectEngine = CreateProjectEngine(builder => builder.AddTagHelpers(descriptors));
+ var projectItem = CreateProjectItem();
+
+ // Act
+ var codeDocument = projectEngine.Process(projectItem);
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(codeDocument.GetDocumentIntermediateNode());
+ }
+
+ private static TagHelperDescriptor CreateTagHelperDescriptor(
+ string tagName,
+ string typeName,
+ string assemblyName,
+ IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null)
+ {
+ var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
+ builder.TypeName(typeName);
+
+ if (attributes != null)
+ {
+ foreach (var attributeBuilder in attributes)
+ {
+ builder.BoundAttributeDescriptor(attributeBuilder);
+ }
+ }
+
+ builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
+
+ var descriptor = builder.Build();
+
+ return descriptor;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TestTagHelperDescriptors.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TestTagHelperDescriptors.cs
new file mode 100644
index 0000000000..d2034b18e0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/IntegrationTests/TestTagHelperDescriptors.cs
@@ -0,0 +1,637 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests
+{
+ public class TestTagHelperDescriptors
+ {
+ public static IEnumerable<TagHelperDescriptor> SimpleTagHelperDescriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "span",
+ typeName: "SpanTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "div",
+ typeName: "DivTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("value")
+ .PropertyName("FooProp")
+ .TypeName("System.String"),
+ builder => builder
+ .Name("bound")
+ .PropertyName("BoundProp")
+ .TypeName("System.String"),
+ builder => builder
+ .Name("age")
+ .PropertyName("AgeProp")
+ .TypeName("System.Int32"),
+ })
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> MinimizedBooleanTagHelperDescriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "span",
+ typeName: "SpanTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "div",
+ typeName: "DivTagHelper",
+ assemblyName: "TestAssembly"),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("value")
+ .PropertyName("FooProp")
+ .TypeName("System.String"),
+ builder => builder
+ .Name("bound")
+ .PropertyName("BoundProp")
+ .TypeName("System.Boolean"),
+ builder => builder
+ .Name("age")
+ .PropertyName("AgeProp")
+ .TypeName("System.Int32"),
+ })
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> CssSelectorTagHelperDescriptors
+ {
+ get
+ {
+ var inputTypePropertyInfo = typeof(TestType).GetRuntimeProperty("Type");
+ var inputCheckedPropertyInfo = typeof(TestType).GetRuntimeProperty("Checked");
+
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "a",
+ typeName: "TestNamespace.ATagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("~/")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.FullMatch)),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "a",
+ typeName: "TestNamespace.ATagHelperMultipleSelectors",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("~/")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.PrefixMatch))
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("?hello=world")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.SuffixMatch)),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("type")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("text")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.FullMatch)),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper2",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("ty")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch)),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("~/")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.PrefixMatch)),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper2",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute
+ .Name("type")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> EnumTagHelperDescriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("catch-all")
+ .PropertyName("CatchAll")
+ .AsEnum()
+ .TypeName($"{typeof(TestTagHelperDescriptors).FullName}.{nameof(MyEnum)}"),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("value")
+ .PropertyName("Value")
+ .AsEnum()
+ .TypeName($"{typeof(TestTagHelperDescriptors).FullName}.{nameof(MyEnum)}"),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> SymbolBoundTagHelperDescriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("[item]")
+ .PropertyName("ListItems")
+ .TypeName("System.Collections.Generic.List<string>"),
+ builder => builder
+ .Name("[(item)]")
+ .PropertyName("ArrayItems")
+ .TypeName(typeof(string[]).FullName),
+ builder => builder
+ .Name("(click)")
+ .PropertyName("Event1")
+ .TypeName(typeof(Action).FullName),
+ builder => builder
+ .Name("(^click)")
+ .PropertyName("Event2")
+ .TypeName(typeof(Action).FullName),
+ builder => builder
+ .Name("*something")
+ .PropertyName("StringProperty1")
+ .TypeName(typeof(string).FullName),
+ builder => builder
+ .Name("#local")
+ .PropertyName("StringProperty2")
+ .TypeName(typeof(string).FullName),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("bound")),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> MinimizedTagHelpers_Descriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("catchall-bound-string")
+ .PropertyName("BoundRequiredString")
+ .TypeName(typeof(string).FullName),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("catchall-unbound-required")),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("input-bound-required-string")
+ .PropertyName("BoundRequiredString")
+ .TypeName(typeof(string).FullName),
+ builder => builder
+ .Name("input-bound-string")
+ .PropertyName("BoundString")
+ .TypeName(typeof(string).FullName),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute.Name("input-bound-required-string"))
+ .RequireAttributeDescriptor(attribute => attribute.Name("input-unbound-required")),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "div",
+ typeName: "DivTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("boundbool")
+ .PropertyName("BoundBoolProp")
+ .TypeName(typeof(bool).FullName),
+ builder => builder
+ .Name("booldict")
+ .PropertyName("BoolDictProp")
+ .TypeName("System.Collections.Generic.IDictionary<string, bool>")
+ .AsDictionaryAttribute("booldict-prefix-", typeof(bool).FullName),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> DynamicAttributeTagHelpers_Descriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("bound")
+ .PropertyName("Bound")
+ .TypeName(typeof(string).FullName)
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> DuplicateTargetTagHelperDescriptors
+ {
+ get
+ {
+ var typePropertyInfo = typeof(TestType).GetRuntimeProperty("Type");
+ var checkedPropertyInfo = typeof(TestType).GetRuntimeProperty("Checked");
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", typePropertyInfo),
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "checked", checkedPropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("type")),
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("checked"))
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", typePropertyInfo),
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "checked", checkedPropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("type")),
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("checked"))
+ })
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> AttributeTargetingTagHelperDescriptors
+ {
+ get
+ {
+ var inputTypePropertyInfo = typeof(TestType).GetRuntimeProperty("Type");
+ var inputCheckedPropertyInfo = typeof(TestType).GetRuntimeProperty("Checked");
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "p",
+ typeName: "TestNamespace.PTagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("class")),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("type")),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper2",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "checked", inputCheckedPropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder
+ .RequireAttributeDescriptor(attribute => attribute.Name("type"))
+ .RequireAttributeDescriptor(attribute => attribute.Name("checked")),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "*",
+ typeName: "TestNamespace.CatchAllTagHelper",
+ assemblyName: "TestAssembly",
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireAttributeDescriptor(attribute => attribute.Name("catchAll")),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> PrefixedAttributeTagHelperDescriptors
+ {
+ get
+ {
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper1",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("int-prefix-grabber")
+ .PropertyName("IntProperty")
+ .TypeName(typeof(int).FullName),
+ builder => builder
+ .Name("int-dictionary")
+ .PropertyName("IntDictionaryProperty")
+ .TypeName("System.Collections.Generic.IDictionary<string, int>")
+ .AsDictionaryAttribute("int-prefix-", typeof(int).FullName),
+ builder => builder
+ .Name("string-prefix-grabber")
+ .PropertyName("StringProperty")
+ .TypeName(typeof(string).FullName),
+ builder => builder
+ .Name("string-dictionary")
+ .PropertyName("StringDictionaryProperty")
+ .TypeName("Namespace.DictionaryWithoutParameterlessConstructor<string, string>")
+ .AsDictionaryAttribute("string-prefix-", typeof(string).FullName),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper2",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => builder
+ .Name("int-dictionary")
+ .PropertyName("IntDictionaryProperty")
+ .TypeName(typeof(int).FullName)
+ .AsDictionaryAttribute("int-prefix-", typeof(int).FullName),
+ builder => builder
+ .Name("string-dictionary")
+ .PropertyName("StringDictionaryProperty")
+ .TypeName("Namespace.DictionaryWithoutParameterlessConstructor<string, string>")
+ .AsDictionaryAttribute("string-prefix-", typeof(string).FullName),
+ }),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> TagHelpersInSectionDescriptors
+ {
+ get
+ {
+ var propertyInfo = typeof(TestType).GetRuntimeProperty("BoundProperty");
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "MyTagHelper",
+ typeName: "TestNamespace.MyTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "BoundProperty", propertyInfo),
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "NestedTagHelper",
+ typeName: "TestNamespace.NestedTagHelper",
+ assemblyName: "TestAssembly"),
+ };
+ }
+ }
+
+ public static IEnumerable<TagHelperDescriptor> DefaultPAndInputTagHelperDescriptors
+ {
+ get
+ {
+ var pAgePropertyInfo = typeof(TestType).GetRuntimeProperty("Age");
+ var inputTypePropertyInfo = typeof(TestType).GetRuntimeProperty("Type");
+ var checkedPropertyInfo = typeof(TestType).GetRuntimeProperty("Checked");
+
+ return new[]
+ {
+ CreateTagHelperDescriptor(
+ tagName: "p",
+ typeName: "TestNamespace.PTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "age", pAgePropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireTagStructure(TagStructure.NormalOrSelfClosing)
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ },
+ ruleBuilders: new Action<TagMatchingRuleDescriptorBuilder>[]
+ {
+ builder => builder.RequireTagStructure(TagStructure.WithoutEndTag)
+ }),
+ CreateTagHelperDescriptor(
+ tagName: "input",
+ typeName: "TestNamespace.InputTagHelper2",
+ assemblyName: "TestAssembly",
+ attributes: new Action<BoundAttributeDescriptorBuilder>[]
+ {
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "type", inputTypePropertyInfo),
+ builder => BuildBoundAttributeDescriptorFromPropertyInfo(builder, "checked", checkedPropertyInfo),
+ }),
+ };
+ }
+ }
+
+ private static TagHelperDescriptor CreateTagHelperDescriptor(
+ string tagName,
+ string typeName,
+ string assemblyName,
+ IEnumerable<Action<BoundAttributeDescriptorBuilder>> attributes = null,
+ IEnumerable<Action<TagMatchingRuleDescriptorBuilder>> ruleBuilders = null)
+ {
+ var builder = TagHelperDescriptorBuilder.Create(typeName, assemblyName);
+ builder.TypeName(typeName);
+
+ if (attributes != null)
+ {
+ foreach (var attributeBuilder in attributes)
+ {
+ builder.BoundAttributeDescriptor(attributeBuilder);
+ }
+ }
+
+ if (ruleBuilders != null)
+ {
+ foreach (var ruleBuilder in ruleBuilders)
+ {
+ builder.TagMatchingRuleDescriptor(innerRuleBuilder =>
+ {
+ innerRuleBuilder.RequireTagName(tagName);
+ ruleBuilder(innerRuleBuilder);
+ });
+ }
+ }
+ else
+ {
+ builder.TagMatchingRuleDescriptor(ruleBuilder => ruleBuilder.RequireTagName(tagName));
+ }
+
+ var descriptor = builder.Build();
+
+ return descriptor;
+ }
+
+ private static void BuildBoundAttributeDescriptorFromPropertyInfo(
+ BoundAttributeDescriptorBuilder builder,
+ string name,
+ PropertyInfo propertyInfo)
+ {
+ builder
+ .Name(name)
+ .PropertyName(propertyInfo.Name)
+ .TypeName(propertyInfo.PropertyType.FullName);
+
+ if (propertyInfo.PropertyType.GetTypeInfo().IsEnum)
+ {
+ builder.AsEnum();
+ }
+ }
+
+ private class TestType
+ {
+ public int Age { get; set; }
+
+ public string Type { get; set; }
+
+ public bool Checked { get; set; }
+
+ public string BoundProperty { get; set; }
+ }
+
+ public enum MyEnum
+ {
+ MyValue,
+ MySecondValue
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DefaultRazorIntermediateNodeBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DefaultRazorIntermediateNodeBuilderTest.cs
new file mode 100644
index 0000000000..f4813684e1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DefaultRazorIntermediateNodeBuilderTest.cs
@@ -0,0 +1,217 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Intermediate
+{
+ public class DefaultRazorIntermediateNodeBuilderTest
+ {
+ [Fact]
+ public void Ctor_CreatesEmptyBuilder()
+ {
+ // Arrange & Act
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+ var current = builder.Current;
+
+ // Assert
+ Assert.Null(current);
+ }
+
+ [Fact]
+ public void Push_WhenEmpty_AddsNode()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Push(node);
+
+ // Assert
+ Assert.Same(node, builder.Current);
+ }
+
+ [Fact]
+ public void Push_WhenNonEmpty_SetsUpChild()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Push(node);
+
+ // Assert
+ Assert.Same(node, builder.Current);
+ Assert.Collection(parent.Children, n => Assert.Same(node, n));
+ }
+
+ [Fact]
+ public void Pop_ThrowsWhenEmpty()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ // Act & Assert
+ ExceptionAssert.Throws<InvalidOperationException>(
+ () => builder.Pop(),
+ "The 'Pop' operation is not valid when the builder is empty.");
+ }
+
+ [Fact]
+ public void Pop_SingleNodeDepth_RemovesAndReturnsNode()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var node = new BasicIntermediateNode();
+ builder.Push(node);
+
+ // Act
+ var result = builder.Pop();
+
+ // Assert
+ Assert.Same(node, result);
+ Assert.Null(builder.Current);
+ }
+
+ [Fact]
+ public void Pop_MultipleNodeDepth_RemovesAndReturnsNode()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var node = new BasicIntermediateNode();
+ builder.Push(node);
+
+ // Act
+ var result = builder.Pop();
+
+ // Assert
+ Assert.Same(node, result);
+ Assert.Same(parent, builder.Current);
+ }
+
+ [Fact]
+ public void Add_AddsToChildrenAndSetsParent()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Add(node);
+
+ // Assert
+ Assert.Same(parent, builder.Current);
+ Assert.Collection(parent.Children, n => Assert.Same(node, n));
+ }
+
+ [Fact]
+ public void Insert_AddsToChildren_EmptyCollection()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Insert(0, node);
+
+ // Assert
+ Assert.Same(parent, builder.Current);
+ Assert.Collection(parent.Children, n => Assert.Same(node, n));
+ }
+
+ [Fact]
+ public void Insert_AddsToChildren_NonEmpyCollection()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var child = new BasicIntermediateNode();
+ builder.Add(child);
+
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Insert(0, node);
+
+ // Assert
+ Assert.Same(parent, builder.Current);
+ Assert.Collection(parent.Children, n => Assert.Same(node, n), n => Assert.Same(child, n));
+ }
+
+ [Fact]
+ public void Insert_AddsToChildren_NonEmpyCollection_AtEnd()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var parent = new BasicIntermediateNode();
+ builder.Push(parent);
+
+ var child = new BasicIntermediateNode();
+ builder.Add(child);
+
+ var node = new BasicIntermediateNode();
+
+ // Act
+ builder.Insert(1, node);
+
+ // Assert
+ Assert.Same(parent, builder.Current);
+ Assert.Collection(parent.Children, n => Assert.Same(child, n), n => Assert.Same(node, n));
+ }
+
+ [Fact]
+ public void Build_PopsMultipleLevels()
+ {
+ // Arrange
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+
+ var document = new DocumentIntermediateNode();
+ builder.Push(document);
+
+ var node = new BasicIntermediateNode();
+ builder.Push(node);
+
+ // Act
+ var result = builder.Build();
+
+ // Assert
+ Assert.Same(document, result);
+ Assert.Null(builder.Current);
+ }
+
+ private class BasicIntermediateNode : IntermediateNode
+ {
+ public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection();
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DocumentIntermediateNodeExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DocumentIntermediateNodeExtensionsTest.cs
new file mode 100644
index 0000000000..8def071acc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/DocumentIntermediateNodeExtensionsTest.cs
@@ -0,0 +1,113 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Intermediate
+{
+ public class DocumentIntermediateNodeExtensionsTest
+ {
+ [Fact]
+ public void FindPrimaryClass_FindsClassWithAnnotation()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var @class = new ClassDeclarationIntermediateNode();
+ @class.Annotations[CommonAnnotations.PrimaryClass] = CommonAnnotations.PrimaryClass;
+
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(@class);
+
+ // Act
+ var result = document.FindPrimaryClass();
+
+ // Assert
+ Assert.Same(@class, result);
+ }
+
+ [Fact]
+ public void FindPrimaryMethod_FindsMethodWithAnnotation()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var method = new MethodDeclarationIntermediateNode();
+ method.Annotations[CommonAnnotations.PrimaryMethod] = CommonAnnotations.PrimaryMethod;
+
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(method);
+
+ // Act
+ var result = document.FindPrimaryMethod();
+
+ // Assert
+ Assert.Same(method, result);
+ }
+
+ [Fact]
+ public void FindPrimaryNamespace_FindsNamespaceWithAnnotation()
+ {
+ // Arrange
+ var document = new DocumentIntermediateNode();
+ var @namespace = new NamespaceDeclarationIntermediateNode();
+ @namespace.Annotations[CommonAnnotations.PrimaryNamespace] = CommonAnnotations.PrimaryNamespace;
+
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Add(@namespace);
+
+ // Act
+ var result = document.FindPrimaryNamespace();
+
+ // Assert
+ Assert.Same(@namespace, result);
+ }
+
+ [Fact]
+ public void FindDirectiveReferences_FindsMatchingDirectives()
+ {
+ // Arrange
+ var directive = DirectiveDescriptor.CreateSingleLineDirective("test");
+ var directive2 = DirectiveDescriptor.CreateSingleLineDirective("test");
+
+ var document = new DocumentIntermediateNode();
+ var @namespace = new NamespaceDeclarationIntermediateNode();
+
+ var builder = IntermediateNodeBuilder.Create(document);
+ builder.Push(@namespace);
+
+ var match1 = new DirectiveIntermediateNode()
+ {
+ Directive = directive,
+ };
+ builder.Add(match1);
+
+ var nonMatch = new DirectiveIntermediateNode()
+ {
+ Directive = directive2,
+ };
+ builder.Add(nonMatch);
+
+ var match2 = new DirectiveIntermediateNode()
+ {
+ Directive = directive,
+ };
+ builder.Add(match2);
+
+ // Act
+ var results = document.FindDirectiveReferences(directive);
+
+ // Assert
+ Assert.Collection(
+ results,
+ r =>
+ {
+ Assert.Same(@namespace, r.Parent);
+ Assert.Same(match1, r.Node);
+ },
+ r =>
+ {
+ Assert.Same(@namespace, r.Parent);
+ Assert.Same(match2, r.Node);
+ });
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/ExtensionIntermediateNodeTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/ExtensionIntermediateNodeTest.cs
new file mode 100644
index 0000000000..a4bf7950ae
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/ExtensionIntermediateNodeTest.cs
@@ -0,0 +1,92 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Intermediate
+{
+ // These tests cover the methods on ExtensionIntermediateNode that are used to implement visitors
+ // that special case an extension node.
+ public class ExtensionIntermediateNodeTest
+ {
+ [Fact]
+ public void Accept_CallsStandardVisitExtension_ForStandardVisitor()
+ {
+ // Arrange
+ var node = new TestExtensionIntermediateNode();
+ var visitor = new StandardVisitor();
+
+ // Act
+ node.Accept(visitor);
+
+ // Assert
+ Assert.True(visitor.WasStandardMethodCalled);
+ Assert.False(visitor.WasSpecificMethodCalled);
+ }
+
+ [Fact]
+ public void Accept_CallsSpecialVisitExtension_ForSpecialVisitor()
+ {
+ // Arrange
+ var node = new TestExtensionIntermediateNode();
+ var visitor = new SpecialVisitor();
+
+ // Act
+ node.Accept(visitor);
+
+ // Assert
+ Assert.False(visitor.WasStandardMethodCalled);
+ Assert.True(visitor.WasSpecificMethodCalled);
+ }
+
+ private class TestExtensionIntermediateNode : ExtensionIntermediateNode
+ {
+ public override IntermediateNodeCollection Children => IntermediateNodeCollection.ReadOnly;
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ // This is the standard visitor boilerplate for an extension node.
+ AcceptExtensionNode<TestExtensionIntermediateNode>(this, visitor);
+ }
+
+ public override void WriteNode(CodeTarget target, CodeRenderingContext context)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private class StandardVisitor : IntermediateNodeVisitor
+ {
+ public bool WasStandardMethodCalled { get; private set; }
+ public bool WasSpecificMethodCalled { get; private set; }
+
+ public override void VisitExtension(ExtensionIntermediateNode node)
+ {
+ WasStandardMethodCalled = true;
+ }
+
+ public void VisitExtension(TestExtensionIntermediateNode node)
+ {
+ WasSpecificMethodCalled = true;
+ }
+ }
+
+ private class SpecialVisitor : IntermediateNodeVisitor, IExtensionIntermediateNodeVisitor<TestExtensionIntermediateNode>
+ {
+ public bool WasStandardMethodCalled { get; private set; }
+ public bool WasSpecificMethodCalled { get; private set; }
+
+ public override void VisitExtension(ExtensionIntermediateNode node)
+ {
+ WasStandardMethodCalled = true;
+ }
+
+ public void VisitExtension(TestExtensionIntermediateNode node)
+ {
+ WasSpecificMethodCalled = true;
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeReferenceTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeReferenceTest.cs
new file mode 100644
index 0000000000..2adbe06a4f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeReferenceTest.cs
@@ -0,0 +1,510 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Intermediate
+{
+ public class IntermediateNodeReferenceTest
+ {
+ [Fact]
+ public void InsertAfter_SingleNode_AddsNodeAfterNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node3);
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act
+ reference.InsertAfter(node2);
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertAfter_SingleNode_AddsNodeAfterNode_AtEnd()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node2);
+
+ var reference = new IntermediateNodeReference(parent, node2);
+
+ // Act
+ reference.InsertAfter(node3);
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertAfter_MultipleNodes_AddsNodesAfterNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+ var node4 = new BasicIntermediateNode("Node4");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node4);
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act
+ reference.InsertAfter(new[] { node2, node3 });
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, node4, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertAfter_MultipleNodes_AddsNodesAfterNode_AtEnd()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+ var node4 = new BasicIntermediateNode("Node4");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node2);
+
+ var reference = new IntermediateNodeReference(parent, node2);
+
+ // Act
+ reference.InsertAfter(new[] { node3, node4 });
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, node4, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertBefore_SingleNode_AddsNodeBeforeNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node3);
+
+ var reference = new IntermediateNodeReference(parent, node3);
+
+ // Act
+ reference.InsertBefore(node2);
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertBefore_SingleNode_AddsNodeBeforeNode_AtBeginning()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+
+ parent.Children.Add(node2);
+ parent.Children.Add(node3);
+
+ var reference = new IntermediateNodeReference(parent, node2);
+
+ // Act
+ reference.InsertBefore(node1);
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertBefore_MultipleNodes_AddsNodesBeforeNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+ var node4 = new BasicIntermediateNode("Node4");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node4);
+
+ var reference = new IntermediateNodeReference(parent, node4);
+
+ // Act
+ reference.InsertBefore(new[] { node2, node3 });
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, node4, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertAfter_MultipleNodes_AddsNodesBeforeNode_AtBeginning()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+ var node4 = new BasicIntermediateNode("Node4");
+
+ parent.Children.Add(node3);
+ parent.Children.Add(node4);
+
+ var reference = new IntermediateNodeReference(parent, node3);
+
+ // Act
+ reference.InsertBefore(new[] { node1, node2 });
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, node4, }, parent.Children);
+ }
+
+ [Fact]
+ public void Remove_RemovesNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node3);
+ parent.Children.Add(node2);
+
+ var reference = new IntermediateNodeReference(parent, node3);
+
+ // Act
+ reference.Remove();
+
+ // Assert
+ Assert.Equal(new[] { node1, node2,}, parent.Children);
+ }
+
+ [Fact]
+ public void Replace_ReplacesNode()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+ var node2 = new BasicIntermediateNode("Node2");
+ var node3 = new BasicIntermediateNode("Node3");
+ var node4 = new BasicIntermediateNode("Node4");
+
+ parent.Children.Add(node1);
+ parent.Children.Add(node4);
+ parent.Children.Add(node3);
+
+ var reference = new IntermediateNodeReference(parent, node4);
+
+ // Act
+ reference.Replace(node2);
+
+ // Assert
+ Assert.Equal(new[] { node1, node2, node3, }, parent.Children);
+ }
+
+ [Fact]
+ public void InsertAfter_SingleNode_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertAfter_MulipleNodes_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_SingleNode_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_MulipleNodes_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void Remove_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Remove());
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void Replace_ThrowsForReferenceNotInitialized()
+ {
+ // Arrange
+ var reference = new IntermediateNodeReference();
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Replace(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. References initialized with the default constructor cannot modify nodes.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertAfter_SingleNode_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new BasicIntermediateNode("_")));
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertAfter_MulipleNodes_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_SingleNode_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new BasicIntermediateNode("_")));
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_MulipleNodes_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void Remove_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Remove());
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void Replace_ThrowsForReadOnlyCollection()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent", IntermediateNodeCollection.ReadOnly);
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Replace(new BasicIntermediateNode("_")));
+ Assert.Equal("The node 'Parent' has a read-only child collection and cannot be modified.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertAfter_SingleNode_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertAfter_MulipleNodes_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertAfter(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_SingleNode_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ [Fact]
+ public void InsertBefore_MulipleNodes_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.InsertBefore(new[] { new BasicIntermediateNode("_") }));
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ [Fact]
+ public void Remove_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Remove());
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ [Fact]
+ public void Replace_ThrowsForNodeNotFound()
+ {
+ // Arrange
+ var parent = new BasicIntermediateNode("Parent");
+
+ var node1 = new BasicIntermediateNode("Node1");
+
+ var reference = new IntermediateNodeReference(parent, node1);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => reference.Replace(new BasicIntermediateNode("_")));
+ Assert.Equal("The reference is invalid. The node 'Node1' could not be found as a child of 'Parent'.", exception.Message);
+ }
+
+ private class BasicIntermediateNode : IntermediateNode
+ {
+ public BasicIntermediateNode(string name)
+ : this(name, new IntermediateNodeCollection())
+ {
+ Name = name;
+ }
+
+ public BasicIntermediateNode(string name, IntermediateNodeCollection children)
+ {
+ Name = name;
+ Children = children;
+ }
+
+ public string Name { get; }
+
+ public override IntermediateNodeCollection Children { get; }
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public override string ToString() => Name;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeWalkerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeWalkerTest.cs
new file mode 100644
index 0000000000..f91735f9c3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Intermediate/IntermediateNodeWalkerTest.cs
@@ -0,0 +1,140 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Intermediate
+{
+ public class IntermediateNodeWalkerTest
+ {
+ [Fact]
+ public void IntermediateNodeWalker_Visit_TraversesEntireGraph()
+ {
+ // Arrange
+ var walker = new DerivedIntermediateNodeWalker();
+
+ var nodes = new IntermediateNode[]
+ {
+ new BasicIntermediateNode("Root"),
+ new BasicIntermediateNode("Root->A"),
+ new BasicIntermediateNode("Root->B"),
+ new BasicIntermediateNode("Root->B->1"),
+ new BasicIntermediateNode("Root->B->2"),
+ new BasicIntermediateNode("Root->C"),
+ };
+
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+ builder.Push(nodes[0]);
+ builder.Add(nodes[1]);
+ builder.Push(nodes[2]);
+ builder.Add(nodes[3]);
+ builder.Add(nodes[4]);
+ builder.Pop();
+ builder.Add(nodes[5]);
+
+ var root = builder.Pop();
+
+ // Act
+ walker.Visit(root);
+
+ // Assert
+ Assert.Equal(nodes, walker.Visited.ToArray());
+ }
+
+ [Fact]
+ public void IntermediateNodeWalker_Visit_SetsParentAndAncestors()
+ {
+ // Arrange
+ var walker = new DerivedIntermediateNodeWalker();
+
+ var nodes = new IntermediateNode[]
+ {
+ new BasicIntermediateNode("Root"),
+ new BasicIntermediateNode("Root->A"),
+ new BasicIntermediateNode("Root->B"),
+ new BasicIntermediateNode("Root->B->1"),
+ new BasicIntermediateNode("Root->B->2"),
+ new BasicIntermediateNode("Root->C"),
+ };
+
+ var ancestors = new Dictionary<string, string[]>()
+ {
+ { "Root", new string[]{ } },
+ { "Root->A", new string[] { "Root" } },
+ { "Root->B", new string[] { "Root" } },
+ { "Root->B->1", new string[] { "Root->B", "Root" } },
+ { "Root->B->2", new string[] { "Root->B", "Root" } },
+ { "Root->C", new string[] { "Root" } },
+ };
+
+ walker.OnVisiting = (n) =>
+ {
+ Assert.Equal(ancestors[((BasicIntermediateNode)n).Name], walker.Ancestors.Cast<BasicIntermediateNode>().Select(b => b.Name));
+ Assert.Equal(ancestors[((BasicIntermediateNode)n).Name].FirstOrDefault(), ((BasicIntermediateNode)walker.Parent)?.Name);
+ };
+
+ var builder = new DefaultRazorIntermediateNodeBuilder();
+ builder.Push(nodes[0]);
+ builder.Add(nodes[1]);
+ builder.Push(nodes[2]);
+ builder.Add(nodes[3]);
+ builder.Add(nodes[4]);
+ builder.Pop();
+ builder.Add(nodes[5]);
+
+ var root = builder.Pop();
+
+ // Act & Assert
+ walker.Visit(root);
+ }
+
+ private class DerivedIntermediateNodeWalker : IntermediateNodeWalker
+ {
+ public new IReadOnlyList<IntermediateNode> Ancestors => base.Ancestors;
+
+ public new IntermediateNode Parent => base.Parent;
+
+ public List<IntermediateNode> Visited { get; } = new List<IntermediateNode>();
+
+ public Action<IntermediateNode> OnVisiting { get; set; }
+
+ public override void VisitDefault(IntermediateNode node)
+ {
+ Visited.Add(node);
+
+ OnVisiting?.Invoke(node);
+ base.VisitDefault(node);
+ }
+
+ public virtual void VisitBasic(BasicIntermediateNode node)
+ {
+ VisitDefault(node);
+ }
+ }
+
+ private class BasicIntermediateNode : IntermediateNode
+ {
+ public BasicIntermediateNode(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; }
+
+ public override IntermediateNodeCollection Children { get; } = new IntermediateNodeCollection();
+
+ public override void Accept(IntermediateNodeVisitor visitor)
+ {
+ ((DerivedIntermediateNodeWalker)visitor).VisitBasic(this);
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/LargeTextSourceDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/LargeTextSourceDocumentTest.cs
new file mode 100644
index 0000000000..fb47799b23
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/LargeTextSourceDocumentTest.cs
@@ -0,0 +1,172 @@
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test
+{
+ public class LargeTextSourceDocumentTest
+ {
+ private const int ChunkTestLength = 10;
+
+ [Fact]
+ public void GetChecksum_ReturnsCopiedChecksum()
+ {
+ // Arrange
+ var contentString = "Hello World";
+ var stream = TestRazorSourceDocument.CreateStreamContent(contentString);
+ var reader = new StreamReader(stream, detectEncodingFromByteOrderMarks: true);
+ var document = new LargeTextSourceDocument(reader, 5, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var firstChecksum = document.GetChecksum();
+ var secondChecksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(firstChecksum, secondChecksum);
+ Assert.NotSame(firstChecksum, secondChecksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF8()
+ {
+ // Arrange
+ var contentString = "Hello World";
+ var stream = TestRazorSourceDocument.CreateStreamContent(contentString);
+ var reader = new StreamReader(stream, detectEncodingFromByteOrderMarks: true);
+ var document = new LargeTextSourceDocument(reader, 5, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 10, 77, 85, 168, 215, 120, 229, 2, 47, 171, 112, 25, 119, 197, 216, 64, 187, 196, 134, 208 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF32()
+ {
+ // Arrange
+ var contentString = "Hello World";
+ var stream = TestRazorSourceDocument.CreateStreamContent(contentString, Encoding.UTF32);
+ var reader = new StreamReader(stream, detectEncodingFromByteOrderMarks: true);
+ var document = new LargeTextSourceDocument(reader, 5, Encoding.UTF32, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 108, 172, 130, 171, 42, 19, 155, 176, 211, 80, 224, 121, 169, 133, 25, 134, 48, 228, 199, 141 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Theory]
+ [InlineData(ChunkTestLength - 1)]
+ [InlineData(ChunkTestLength)]
+ [InlineData(ChunkTestLength + 1)]
+ [InlineData(ChunkTestLength * 2 - 1)]
+ [InlineData(ChunkTestLength * 2)]
+ [InlineData(ChunkTestLength * 2 + 1)]
+ public void Indexer_ProvidesCharacterAccessToContent(int contentLength)
+ {
+ // Arrange
+ var content = new char[contentLength];
+
+ for (var i = 0; i < contentLength - 1; i++)
+ {
+ content[i] = 'a';
+ }
+ content[contentLength - 1] = 'b';
+ var contentString = new string(content);
+
+ var stream = TestRazorSourceDocument.CreateStreamContent(new string(content));
+ var reader = new StreamReader(stream, true);
+ var document = new LargeTextSourceDocument(reader, ChunkTestLength, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var output = new char[contentLength];
+ for (var i = 0; i < document.Length; i++)
+ {
+ output[i] = document[i];
+ }
+ var outputString = new string(output);
+
+ // Assert
+ Assert.Equal(contentLength, document.Length);
+ Assert.Equal(contentString, outputString);
+ }
+
+ [Theory]
+ [InlineData("test.cshtml")]
+ [InlineData(null)]
+ public void FilePath(string filePath)
+ {
+ // Arrange
+ var stream = TestRazorSourceDocument.CreateStreamContent("abc");
+ var reader = new StreamReader(stream, true);
+
+ // Act
+ var document = new LargeTextSourceDocument(reader, ChunkTestLength, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: filePath, relativePath: null));
+
+ // Assert
+ Assert.Equal(filePath, document.FilePath);
+ }
+
+ [Theory]
+ [InlineData("test.cshtml")]
+ [InlineData(null)]
+ public void RelativePath(string relativePath)
+ {
+ // Arrange
+ var stream = TestRazorSourceDocument.CreateStreamContent("abc");
+ var reader = new StreamReader(stream, true);
+
+ // Act
+ var document = new LargeTextSourceDocument(reader, ChunkTestLength, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: relativePath));
+
+ // Assert
+ Assert.Equal(relativePath, document.RelativePath);
+ }
+
+ [Fact]
+ public void Lines()
+ {
+ // Arrange
+ var stream = TestRazorSourceDocument.CreateStreamContent("abc\ndef\nghi");
+ var reader = new StreamReader(stream, true);
+
+ // Act
+ var document = new LargeTextSourceDocument(reader, ChunkTestLength, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Assert
+ Assert.Equal(3, document.Lines.Count);
+ }
+
+ [Theory]
+ [InlineData("", 0, 0, 0)] // Nothing to copy
+ [InlineData("a", 0, 100, 1)] // Destination index different from start
+ [InlineData("j", ChunkTestLength - 1, 0, 1)] // One char just before the chunk limit
+ [InlineData("k", ChunkTestLength, 0, 1)] // One char one the chunk limit
+ [InlineData("l", ChunkTestLength + 1, 0, 1)] // One char just after the chunk limit
+ [InlineData("jk", ChunkTestLength - 1, 0, 2)] // Two char that are on both chunk sides
+ [InlineData("abcdefghijklmnopqrstuvwxy", 0, 100, 25)] // Everything except the last
+ [InlineData("abcdefghijklmnopqrstuvwxyz", 0, 0, 26)] // Copy all
+ [InlineData("xyz", 23, 0, 3)] // The last chars
+ public void CopyTo(string expected, int sourceIndex, int destinationIndex, int count)
+ {
+ // Arrange
+ var stream = TestRazorSourceDocument.CreateStreamContent("abcdefghijklmnopqrstuvwxyz");
+
+ var reader = new StreamReader(stream, true);
+ var document = new LargeTextSourceDocument(reader, ChunkTestLength, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var destination = new char[1000];
+ document.CopyTo(sourceIndex, destination, destinationIndex, count);
+
+ // Assert
+ var copy = new string(destination, destinationIndex, count);
+ Assert.Equal(expected, copy);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BaselineWriter.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BaselineWriter.cs
new file mode 100644
index 0000000000..eee1a8fd58
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BaselineWriter.cs
@@ -0,0 +1,46 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Diagnostics;
+using System.IO;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public static class BaselineWriter
+ {
+ private static object baselineLock = new object();
+
+ [Conditional("GENERATE_BASELINES")]
+ public static void WriteBaseline(string baselineFile, string output)
+ {
+ var root = RecursiveFind("Razor.sln", Path.GetFullPath("."));
+ var baselinePath = Path.Combine(root, baselineFile);
+
+ // Serialize writes to minimize contention for file handles and directory access.
+ lock (baselineLock)
+ {
+ // Update baseline
+ using (var stream = File.Open(baselinePath, FileMode.Create, FileAccess.Write))
+ {
+ using (var writer = new StreamWriter(stream))
+ {
+ writer.Write(output);
+ }
+ }
+ }
+ }
+
+ private static string RecursiveFind(string path, string start)
+ {
+ var test = Path.Combine(start, path);
+ if (File.Exists(test))
+ {
+ return start;
+ }
+ else
+ {
+ return RecursiveFind(path, new DirectoryInfo(start).Parent.FullName);
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTest.cs
new file mode 100644
index 0000000000..4b4f984ce6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/BlockTest.cs
@@ -0,0 +1,118 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class BlockTest
+ {
+ [Fact]
+ public void ChildChanged_NotifiesParent()
+ {
+ // Arrange
+ var spanBuilder = new SpanBuilder(SourceLocation.Zero);
+ spanBuilder.Accept(new HtmlSymbol("hello", HtmlSymbolType.Text));
+ var span = spanBuilder.Build();
+ var blockBuilder = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Markup,
+ };
+ blockBuilder.Children.Add(span);
+ var childBlock = blockBuilder.Build();
+ blockBuilder = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Markup,
+ };
+ blockBuilder.Children.Add(childBlock);
+ var parentBlock = blockBuilder.Build();
+ var originalBlockLength = parentBlock.Length;
+ spanBuilder = new SpanBuilder(SourceLocation.Zero);
+ spanBuilder.Accept(new HtmlSymbol("hi", HtmlSymbolType.Text));
+ span.ReplaceWith(spanBuilder);
+
+ // Wire up parents now so we can re-trigger ChildChanged to cause cache refresh.
+ span.Parent = childBlock;
+ childBlock.Parent = parentBlock;
+
+ // Act
+ childBlock.ChildChanged();
+
+ // Assert
+ Assert.Equal(5, originalBlockLength);
+ Assert.Equal(2, parentBlock.Length);
+ }
+
+ [Fact]
+ public void Clone_ClonesBlock()
+ {
+ // Arrange
+ var blockBuilder = new BlockBuilder()
+ {
+ ChunkGenerator = new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>("class=\"", SourceLocation.Zero), 0, 0, 0),
+ Type = BlockKindInternal.Expression,
+ };
+ blockBuilder.Children.Add(new SpanBuilder(new SourceLocation(1, 2, 3)).Build());
+ var block = blockBuilder.Build();
+
+ // Act
+ var copy = (Block)block.Clone();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(copy, block);
+ Assert.NotSame(block, copy);
+ }
+
+ [Fact]
+ public void ConstructorWithBlockBuilderSetsParent()
+ {
+ // Arrange
+ var builder = new BlockBuilder() { Type = BlockKindInternal.Comment };
+ var span = new SpanBuilder(SourceLocation.Undefined) { Kind = SpanKindInternal.Code }.Build();
+ builder.Children.Add(span);
+
+ // Act
+ var block = builder.Build();
+
+ // Assert
+ Assert.Same(block, span.Parent);
+ }
+
+ [Fact]
+ public void ConstructorTransfersInstanceOfChunkGeneratorFromBlockBuilder()
+ {
+ // Arrange
+ var expected = new ExpressionChunkGenerator();
+ var builder = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Statement,
+ ChunkGenerator = expected
+ };
+
+ // Act
+ var actual = builder.Build();
+
+ // Assert
+ Assert.Same(expected, actual.ChunkGenerator);
+ }
+
+ [Fact]
+ public void ConstructorTransfersChildrenFromBlockBuilder()
+ {
+ // Arrange
+ var expected = new SpanBuilder(SourceLocation.Undefined) { Kind = SpanKindInternal.Code }.Build();
+ var builder = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Statement
+ };
+ builder.Children.Add(expected);
+
+ // Act
+ var block = builder.Build();
+
+ // Assert
+ Assert.Same(expected, block.Children.Single());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs
new file mode 100644
index 0000000000..13633efdd1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs
@@ -0,0 +1,144 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpAutoCompleteTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void FunctionsDirectiveAutoCompleteAtEOF()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(FunctionsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 1), FunctionsDirective.Directive.Directive, "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "@functions{",
+ new[] { FunctionsDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void SectionDirectiveAutoCompleteAtEOF()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 1), "section", "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "@section Header {",
+ new[] { SectionDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier)
+ .AsDirectiveToken(SectionDirective.Directive.Tokens.First()),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.EmptyHtml())));
+ }
+
+ [Fact]
+ public void VerbatimBlockAutoCompleteAtEOF()
+ {
+ ParseBlockTest("@{",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" })
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void FunctionsDirectiveAutoCompleteAtStartOfFile()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(FunctionsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 1), "functions", "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "@functions{" + Environment.NewLine + "foo",
+ new[] { FunctionsDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + "foo").AsStatement()));
+ }
+
+ [Fact]
+ public void SectionDirectiveAutoCompleteAtStartOfFile()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 1), "section", "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "@section Header {" + Environment.NewLine + "<p>Foo</p>",
+ new[] { SectionDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens.First()),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")))));
+ }
+
+ [Fact]
+ public void VerbatimBlockAutoCompleteAtStartOfFile()
+ {
+ ParseBlockTest(
+ "@{" + Environment.NewLine + "<p></p>",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine)
+ .AsStatement()
+ .With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" }),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.Span(SpanKindInternal.Code, new CSharpSymbol(string.Empty, CSharpSymbolType.Unknown))
+ .With(new StatementChunkGenerator())
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpBlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpBlockTest.cs
new file mode 100644
index 0000000000..fa22393a46
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpBlockTest.cs
@@ -0,0 +1,1256 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpBlockTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void ParseBlock_NestedCodeBlockWithCSharpAt()
+ {
+ ParseBlockTest("{ if (true) { var val = @x; if (val != 3) { } } }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Code(" if (true) { var val = @x; if (val != 3) { } } ")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.Any)
+ .AutoCompleteWith(autoCompleteString: null, atEndOfSpan: false),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlock_NestedCodeBlockWithMarkupSetsDotAsMarkup()
+ {
+ ParseBlockTest("if (true) { @if(false) { <div>@something.</div> } }",
+ new StatementBlock(
+ Factory.Code("if (true) { ").AsStatement(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(false) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<div>", AcceptedCharactersInternal.None),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("something")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("."),
+ BlockFactory.MarkupTagBlock("</div>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement()),
+ Factory.Code(" }").AsStatement()));
+ }
+
+ [Fact]
+ public void BalancingBracketsIgnoresStringLiteralCharactersAndBracketsInsideSingleLineComments()
+ {
+ SingleSpanBlockTest(@"if(foo) {
+ // bar } "" baz '
+ zoop();
+}", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void NestedCodeBlockWithAtDoesntCauseError()
+ {
+ ParseBlockTest("if (true) { @if(false) { } }",
+ new StatementBlock(
+ Factory.Code("if (true) { ").AsStatement(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(false) { }").AsStatement()
+ ),
+ Factory.Code(" }").AsStatement()));
+ }
+
+ [Fact]
+ public void BalancingBracketsIgnoresStringLiteralCharactersAndBracketsInsideBlockComments()
+ {
+ SingleSpanBlockTest(
+ @"if(foo) {
+ /* bar } "" */ ' baz } '
+ zoop();
+}", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsForKeyword()
+ {
+ SingleSpanBlockTest(
+ "for(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsForeachKeyword()
+ {
+ SingleSpanBlockTest(
+ "foreach(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsWhileKeyword()
+ {
+ SingleSpanBlockTest(
+ "while(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsUsingKeywordFollowedByParen()
+ {
+ SingleSpanBlockTest(
+ "using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsUsingsNestedWithinOtherBlocks()
+ {
+ SingleSpanBlockTest(
+ "if(foo) { using(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); } }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsIfKeywordWithNoElseBranches()
+ {
+ SingleSpanBlockTest(
+ "if(int i = 0; i < 10; new Foo { Bar = \"baz\" }) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockAllowsEmptyBlockStatement()
+ {
+ SingleSpanBlockTest("if(false) { }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesParenBalancingAtEOF()
+ {
+ ImplicitExpressionTest(
+ "Html.En(code()", "Html.En(code()",
+ AcceptedCharactersInternal.Any,
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenIfAndElseClause()
+ {
+ SingleSpanBlockTest(
+ "if(foo) { bar(); } /* Foo */ /* Bar */ else { baz(); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenIfAndElseClause()
+ {
+ RunRazorCommentBetweenClausesTest(
+ "if(foo) { bar(); } ", " else { baz(); }",
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenElseIfAndElseClause()
+ {
+ SingleSpanBlockTest(
+ "if(foo) { bar(); } else if(bar) { baz(); } /* Foo */ /* Bar */ else { biz(); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenElseIfAndElseClause()
+ {
+ RunRazorCommentBetweenClausesTest(
+ "if(foo) { bar(); } else if(bar) { baz(); } ", " else { baz(); }",
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenIfAndElseIfClause()
+ {
+ SingleSpanBlockTest(
+ "if(foo) { bar(); } /* Foo */ /* Bar */ else if(bar) { baz(); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenIfAndElseIfClause()
+ {
+ RunRazorCommentBetweenClausesTest("if(foo) { bar(); } ", " else if(bar) { baz(); }");
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenIfAndElseClause()
+ {
+ SingleSpanBlockTest(@"if(foo) { bar(); }
+// Foo
+// Bar
+else { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenElseIfAndElseClause()
+ {
+ SingleSpanBlockTest(@"if(foo) { bar(); } else if(bar) { baz(); }
+// Foo
+// Bar
+else { biz(); }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenIfAndElseIfClause()
+ {
+ SingleSpanBlockTest(@"if(foo) { bar(); }
+// Foo
+// Bar
+else if(bar) { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockParsesElseIfBranchesOfIfStatement()
+ {
+ const string ifStatement = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+ const string elseIfBranch = @" else if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""bar } baz"");
+}";
+ const string document = ifStatement + elseIfBranch;
+
+ SingleSpanBlockTest(document, BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockParsesMultipleElseIfBranchesOfIfStatement()
+ {
+ const string ifStatement = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+ const string elseIfBranch = @" else if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""bar } baz"");
+}";
+ const string document = ifStatement + elseIfBranch + elseIfBranch + elseIfBranch + elseIfBranch;
+ SingleSpanBlockTest(document, BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockParsesMultipleElseIfBranchesOfIfStatementFollowedByOneElseBranch()
+ {
+ const string ifStatement = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+ const string elseIfBranch = @" else if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""bar } baz"");
+}";
+ const string elseBranch = @" else { Debug.WriteLine(@""bar } baz""); }";
+ const string document = ifStatement + elseIfBranch + elseIfBranch + elseBranch;
+
+ SingleSpanBlockTest(document, BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockStopsParsingCodeAfterElseBranch()
+ {
+ const string ifStatement = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+ const string elseIfBranch = @" else if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""bar } baz"");
+}";
+ const string elseBranch = @" else { Debug.WriteLine(@""bar } baz""); }";
+ const string document = ifStatement + elseIfBranch + elseBranch + elseIfBranch;
+ const string expected = ifStatement + elseIfBranch + elseBranch;
+
+ ParseBlockTest(
+ document,
+ new StatementBlock(Factory.Code(expected).AsStatement().Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockStopsParsingIfIfStatementNotFollowedByElse()
+ {
+ const string document = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+
+ SingleSpanBlockTest(document, BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockAcceptsElseIfWithNoCondition()
+ {
+ // We don't want to be a full C# parser - If the else if is missing it's condition, the C# compiler
+ // can handle that, we have all the info we need to keep parsing
+ const string ifBranch = @"if(int i = 0; i < 10; new Foo { Bar = ""baz"" }) {
+ Debug.WriteLine(@""foo } bar"");
+}";
+ const string elseIfBranch = @" else if { foo(); }";
+ const string document = ifBranch + elseIfBranch;
+
+ SingleSpanBlockTest(document, BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesDoWhileBlock()
+ {
+ SingleSpanBlockTest(
+ "do { var foo = bar; } while(foo != bar);",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesDoWhileBlockMissingSemicolon()
+ {
+ SingleSpanBlockTest("do { var foo = bar; } while(foo != bar)", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesDoWhileBlockMissingWhileCondition()
+ {
+ SingleSpanBlockTest("do { var foo = bar; } while", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesDoWhileBlockMissingWhileConditionWithSemicolon()
+ {
+ SingleSpanBlockTest(
+ "do { var foo = bar; } while;",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesDoWhileBlockMissingWhileClauseEntirely()
+ {
+ SingleSpanBlockTest("do { var foo = bar; } narf;", "do { var foo = bar; }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenDoAndWhileClause()
+ {
+ SingleSpanBlockTest(
+ "do { var foo = bar; } /* Foo */ /* Bar */ while(true);",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenDoAndWhileClause()
+ {
+ SingleSpanBlockTest(@"do { var foo = bar; }
+// Foo
+// Bar
+while(true);", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenDoAndWhileClause()
+ {
+ RunRazorCommentBetweenClausesTest(
+ "do { var foo = bar; } ", " while(true);",
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesMarkupInDoWhileBlock()
+ {
+ ParseBlockTest("@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("do { var foo = bar;").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("foo++; } while (foo<bar>);").AsStatement().Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsSwitchKeyword()
+ {
+ SingleSpanBlockTest(@"switch(foo) {
+ case 0:
+ break;
+ case 1:
+ {
+ break;
+ }
+ case 2:
+ return;
+ default:
+ return;
+}", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSkipsParenthesisedExpressionAndThenBalancesBracesIfFirstIdentifierIsLockKeyword()
+ {
+ SingleSpanBlockTest(
+ "lock(foo) { Debug.WriteLine(@\"foo } bar\"); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockHasErrorsIfNamespaceImportMissingSemicolon()
+ {
+ NamespaceImportTest(
+ "using Foo.Bar.Baz",
+ " Foo.Bar.Baz",
+ acceptedCharacters: AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace,
+ location: new SourceLocation(17, 0, 17));
+ }
+
+ [Fact]
+ public void ParseBlockHasErrorsIfNamespaceAliasMissingSemicolon()
+ {
+ NamespaceImportTest(
+ "using Foo.Bar.Baz = FooBarBaz",
+ " Foo.Bar.Baz = FooBarBaz",
+ acceptedCharacters: AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace,
+ location: new SourceLocation(29, 0, 29));
+ }
+
+ [Fact]
+ public void ParseBlockParsesNamespaceImportWithSemicolonForUsingKeywordIfIsInValidFormat()
+ {
+ NamespaceImportTest(
+ "using Foo.Bar.Baz;",
+ " Foo.Bar.Baz",
+ AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace);
+ }
+
+ [Fact]
+ public void ParseBlockDoesntCaptureWhitespaceAfterUsing()
+ {
+ ParseBlockTest("using Foo ",
+ new DirectiveBlock(
+ Factory.Code("using Foo")
+ .AsNamespaceImport(" Foo")
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void ParseBlockCapturesNewlineAfterUsing()
+ {
+ ParseBlockTest($"using Foo{Environment.NewLine}",
+ new DirectiveBlock(
+ Factory.Code($"using Foo{Environment.NewLine}")
+ .AsNamespaceImport(" Foo")
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void ParseBlockParsesNamespaceAliasWithSemicolonForUsingKeywordIfIsInValidFormat()
+ {
+ NamespaceImportTest(
+ "using FooBarBaz = FooBarBaz;",
+ " FooBarBaz = FooBarBaz",
+ AcceptedCharactersInternal.NonWhiteSpace | AcceptedCharactersInternal.WhiteSpace);
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesUsingKeywordAtEOFAndOutputsFileCodeBlock()
+ {
+ SingleSpanBlockTest("using ", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesSingleLineCommentAtEndOfFile()
+ {
+ const string document = "foreach(var f in Foo) { // foo bar baz";
+ SingleSpanBlockTest(
+ document,
+ document,
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "foreach", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesBlockCommentAtEndOfFile()
+ {
+ const string document = "foreach(var f in Foo) { /* foo bar baz";
+ SingleSpanBlockTest(
+ document,
+ document,
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_BlockCommentNotTerminated(
+ new SourceSpan(new SourceLocation(24, 0, 24), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "foreach", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesSingleSlashAtEndOfFile()
+ {
+ const string document = "foreach(var f in Foo) { / foo bar baz";
+ SingleSpanBlockTest(
+ document,
+ document,
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "foreach", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenTryAndFinallyClause()
+ {
+ SingleSpanBlockTest("try { bar(); } /* Foo */ /* Bar */ finally { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenTryAndFinallyClause()
+ {
+ RunRazorCommentBetweenClausesTest("try { bar(); } ", " finally { biz(); }", acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenCatchAndFinallyClause()
+ {
+ SingleSpanBlockTest(
+ "try { bar(); } catch(bar) { baz(); } /* Foo */ /* Bar */ finally { biz(); }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenCatchAndFinallyClause()
+ {
+ RunRazorCommentBetweenClausesTest(
+ "try { bar(); } catch(bar) { baz(); } ", " finally { biz(); }",
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsBlockCommentBetweenTryAndCatchClause()
+ {
+ SingleSpanBlockTest("try { bar(); } /* Foo */ /* Bar */ catch(bar) { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsRazorCommentBetweenTryAndCatchClause()
+ {
+ RunRazorCommentBetweenClausesTest("try { bar(); }", " catch(bar) { baz(); }");
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenTryAndFinallyClause()
+ {
+ SingleSpanBlockTest(@"try { bar(); }
+// Foo
+// Bar
+finally { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenCatchAndFinallyClause()
+ {
+ SingleSpanBlockTest(@"try { bar(); } catch(bar) { baz(); }
+// Foo
+// Bar
+finally { biz(); }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsLineCommentBetweenTryAndCatchClause()
+ {
+ SingleSpanBlockTest(@"try { bar(); }
+// Foo
+// Bar
+catch(bar) { baz(); }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsTryStatementWithNoAdditionalClauses()
+ {
+ SingleSpanBlockTest("try { var foo = new { } }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupWithinTryClause()
+ {
+ RunSimpleWrappedMarkupTest(
+ prefix: "try {",
+ markup: " <p>Foo</p> ",
+ suffix: "}",
+ expectedStart: new SourceLocation(5, 0, 5),
+ expectedMarkup: new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsTryStatementWithOneCatchClause()
+ {
+ SingleSpanBlockTest("try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupWithinCatchClause()
+ {
+ RunSimpleWrappedMarkupTest(
+ prefix: "try { var foo = new { } } catch(Foo Bar Baz) {",
+ markup: " <p>Foo</p> ",
+ suffix: "}",
+ expectedStart: new SourceLocation(46, 0, 46),
+ expectedMarkup: new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsTryStatementWithMultipleCatchClause()
+ {
+ SingleSpanBlockTest(
+ "try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) " +
+ "{ var foo = new { } } catch(Foo Bar Baz) { var foo = new { } }",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsExceptionLessCatchClauses()
+ {
+ SingleSpanBlockTest("try { var foo = new { } } catch { var foo = new { } }", BlockKindInternal.Statement, SpanKindInternal.Code);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupWithinAdditionalCatchClauses()
+ {
+ RunSimpleWrappedMarkupTest(
+ prefix: "try { var foo = new { } } catch(Foo Bar Baz) { var foo = new { } } catch(Foo Bar Baz) " +
+ "{ var foo = new { } } catch(Foo Bar Baz) {",
+ markup: " <p>Foo</p> ",
+ suffix: "}",
+ expectedStart: new SourceLocation(128, 0, 128),
+ expectedMarkup: new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsTryStatementWithFinallyClause()
+ {
+ SingleSpanBlockTest("try { var foo = new { } } finally { var foo = new { } }", BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupWithinFinallyClause()
+ {
+ RunSimpleWrappedMarkupTest(
+ prefix: "try { var foo = new { } } finally {",
+ markup: " <p>Foo</p> ",
+ suffix: "}",
+ expectedStart: new SourceLocation(35, 0, 35),
+ expectedMarkup: new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockStopsParsingCatchClausesAfterFinallyBlock()
+ {
+ var expectedContent = "try { var foo = new { } } finally { var foo = new { } }";
+ SingleSpanBlockTest(expectedContent + " catch(Foo Bar Baz) { }", expectedContent, BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotAllowMultipleFinallyBlocks()
+ {
+ var expectedContent = "try { var foo = new { } } finally { var foo = new { } }";
+ SingleSpanBlockTest(expectedContent + " finally { }", expectedContent, BlockKindInternal.Statement, SpanKindInternal.Code, acceptedCharacters: AcceptedCharactersInternal.None);
+ }
+
+ [Fact]
+ public void ParseBlockAcceptsTrailingDotIntoImplicitExpressionWhenEmbeddedInCode()
+ {
+ // Arrange
+ ParseBlockTest(@"if(foo) { @foo. }",
+ new StatementBlock(
+ Factory.Code("if(foo) { ").AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo.")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.Code(" }").AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockParsesExpressionOnSwitchCharacterFollowedByOpenParen()
+ {
+ // Arrange
+ ParseBlockTest(@"if(foo) { @(foo + bar) }",
+ new StatementBlock(
+ Factory.Code("if(foo) { ").AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("foo + bar").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code(" }").AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockParsesExpressionOnSwitchCharacterFollowedByIdentifierStart()
+ {
+ // Arrange
+ ParseBlockTest(@"if(foo) { @foo[4].bar() }",
+ new StatementBlock(
+ Factory.Code("if(foo) { ").AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo[4].bar()")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.Code(" }").AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockTreatsDoubleAtSignAsEscapeSequenceIfAtStatementStart()
+ {
+ // Arrange
+ ParseBlockTest(@"if(foo) { @@class.Foo() }",
+ new StatementBlock(
+ Factory.Code("if(foo) { ").AsStatement(),
+ Factory.Code("@").Hidden(),
+ Factory.Code("@class.Foo() }").AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockTreatsAtSignsAfterFirstPairAsPartOfCSharpStatement()
+ {
+ // Arrange
+ ParseBlockTest(@"if(foo) { @@@@class.Foo() }",
+ new StatementBlock(
+ Factory.Code("if(foo) { ").AsStatement(),
+ Factory.Code("@").Hidden(),
+ Factory.Code("@@@class.Foo() }").AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotParseMarkupStatementOrExpressionOnSwitchCharacterNotFollowedByOpenAngleOrColon()
+ {
+ // Arrange
+ ParseBlockTest("if(foo) { @\"Foo\".ToString(); }",
+ new StatementBlock(
+ Factory.Code("if(foo) { @\"Foo\".ToString(); }").AsStatement()));
+ }
+
+ [Fact]
+ public void ParsersCanNestRecursively()
+ {
+ // Arrange
+ ParseBlockTest("foreach(var c in db.Categories) {" + Environment.NewLine
+ + " <div>" + Environment.NewLine
+ + " <h1>@c.Name</h1>" + Environment.NewLine
+ + " <ul>" + Environment.NewLine
+ + " @foreach(var p in c.Products) {" + Environment.NewLine
+ + " <li><a href=\"@Html.ActionUrl(\"Products\", \"Detail\", new { id = p.Id })\">@p.Name</a></li>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " </ul>" + Environment.NewLine
+ + " </div>" + Environment.NewLine
+ + " }",
+ new StatementBlock(
+ Factory.Code("foreach(var c in db.Categories) {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<div>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine + " "),
+ BlockFactory.MarkupTagBlock("<h1>", AcceptedCharactersInternal.None),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("c.Name")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ BlockFactory.MarkupTagBlock("</h1>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine + " "),
+ BlockFactory.MarkupTagBlock("<ul>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.Code(@" ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code("foreach(var p in c.Products) {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<li>", AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ "href",
+ new LocationTagged<string>(" href=\"", 183 + Environment.NewLine.Length * 5, 5, 30),
+ new LocationTagged<string>("\"", 246 + Environment.NewLine.Length * 5, 5, 93)),
+ Factory.Markup(" href=\"").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(string.Empty, 190 + Environment.NewLine.Length * 5, 5, 37), 190 + Environment.NewLine.Length * 5, 5, 37),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("Html.ActionUrl(\"Products\", \"Detail\", new { id = p.Id })")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p.Name")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ BlockFactory.MarkupTagBlock("</a>", AcceptedCharactersInternal.None),
+ BlockFactory.MarkupTagBlock("</li>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }" + Environment.NewLine).AsStatement().Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("</ul>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine + " "),
+ BlockFactory.MarkupTagBlock("</div>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }").AsStatement().Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ public static TheoryData BlockWithEscapedTransitionData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var datetimeBlock = new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace));
+
+ return new TheoryData<string, Block>
+ {
+ {
+ // Double transition in attribute value
+ "{<span foo='@@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 14, 0, 14)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("@", 12, 0, 12))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition at the end of attribute value
+ "{<span foo='abc@@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 17, 0, 17)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("abc", 12, 0, 12))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("@", 15, 0, 15))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition at the beginning attribute value
+ "{<span foo='@@def' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 17, 0, 17)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("@", 12, 0, 12))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("def").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 14, 0, 14), new LocationTagged<string>("def", 14, 0, 14))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition in between attribute value
+ "{<span foo='abc @@ def' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 22, 0, 22)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("abc", 12, 0, 12))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 15, 0, 15), new LocationTagged<string>("@", 16, 0, 16))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup(" def").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 18, 0, 18), new LocationTagged<string>("def", 19, 0, 19))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition with expression block
+ "{<span foo='@@@DateTime.Now' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 27, 0, 27)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("@", 12, 0, 12))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 14, 0, 14), 14, 0, 14),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ datetimeBlock),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ "{<span foo='@DateTime.Now @@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 28, 0, 28)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), 12, 0, 12),
+ datetimeBlock),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 25, 0, 25), new LocationTagged<string>("@", 26, 0, 26))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ "{<span foo='@DateTime.Now@@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 27, 0, 27)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), 12, 0, 12),
+ datetimeBlock),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 25, 0, 25), new LocationTagged<string>("@", 25, 0, 25))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ "{<span foo='@(2+3)@@@DateTime.Now' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 33, 0, 33)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), 12, 0, 12),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("(").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None),
+ factory.Code("2+3").AsExpression(),
+ factory.MetaCode(")").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 18, 0, 18), new LocationTagged<string>("@", 18, 0, 18))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 20, 0, 20), 20, 0, 20),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ datetimeBlock),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ "{<span foo='@@@(2+3)' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 20, 0, 20)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("@", 12, 0, 12))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 14, 0, 14), 14, 0, 14),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("(").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None),
+ factory.Code("2+3").AsExpression(),
+ factory.MetaCode(")").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition with email in attribute value
+ "{<span foo='abc@def.com @@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 26, 0, 26)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc@def.com").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("abc@def.com", 12, 0, 12))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 23, 0, 23), new LocationTagged<string>("@", 24, 0, 24))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ "{<span foo='abc@@def.com @@' />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 27, 0, 27)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("abc", 12, 0, 12))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("@", 15, 0, 15))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("def.com").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 17, 0, 17), new LocationTagged<string>("def.com", 17, 0, 17))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 24, 0, 24), new LocationTagged<string>("@", 25, 0, 25))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ {
+ // Double transition in complex regex in attribute value
+ @"{<span foo=""/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@@[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i"" />}",
+ CreateStatementBlock(
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo=\"", 6, 0, 6), new LocationTagged<string>("\"", 112, 0, 112)),
+ factory.Markup(" foo=\"").With(SpanChunkGenerator.Null),
+ factory.Markup(@"/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>(@"/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+", 12, 0, 12))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 44, 0, 44), new LocationTagged<string>("@", 44, 0, 44))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup(@"[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 46, 0, 46), new LocationTagged<string>(@"[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i", 46, 0, 46))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(BlockWithEscapedTransitionData))]
+ public void ParseBlock_WithDoubleTransition_DoesNotThrow(string input, object expected)
+ {
+ FixupSpans = true;
+
+ // Act & Assert
+ ParseBlockTest(input, (Block)expected);
+ }
+
+ [Fact]
+ public void ParseBlock_WithDoubleTransition_EndOfFile_Throws()
+ {
+ // Arrange
+ var expected = new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>(string.Empty, 14, 0, 14)),
+ Factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ Factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), new LocationTagged<string>("@", 12, 0, 12))).Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)))),
+ Factory.EmptyHtml()));
+ var expectedErrors = new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 4), "span"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ };
+
+ // Act & Assert
+ ParseBlockTest("{<span foo='@@", expected, expectedErrors);
+ }
+
+ [Fact]
+ public void ParseBlock_WithUnexpectedTransitionsInAttributeValue_Throws()
+ {
+ // Arrange
+ var expected = new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 6, 0, 6), new LocationTagged<string>("'", 15, 0, 15)),
+ Factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 12, 0, 12), 12, 0, 12),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(" ", 13, 0, 13), 13, 0, 13),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None));
+ var expectedErrors = new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(13, 0, 13), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 5),
+ "' />}"),
+ };
+
+ // Act & Assert
+ ParseBlockTest("{<span foo='@ @' />}", expected, expectedErrors);
+ }
+
+ private void RunRazorCommentBetweenClausesTest(string preComment, string postComment, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
+ {
+ ParseBlockTest(preComment + "@* Foo *@ @* Bar *@" + postComment,
+ new StatementBlock(
+ Factory.Code(preComment).AsStatement(),
+ new CommentBlock(
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.Comment(" Foo ", CSharpSymbolType.RazorComment),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ ),
+ Factory.Code(" ").AsStatement(),
+ new CommentBlock(
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.Comment(" Bar ", CSharpSymbolType.RazorComment),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ ),
+ Factory.Code(postComment).AsStatement().Accepts(acceptedCharacters)));
+ }
+
+ private void RunSimpleWrappedMarkupTest(string prefix, string markup, string suffix, MarkupBlock expectedMarkup, SourceLocation expectedStart, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
+ {
+ var expected = new StatementBlock(
+ Factory.Code(prefix).AsStatement(),
+ expectedMarkup,
+ Factory.Code(suffix).AsStatement().Accepts(acceptedCharacters));
+
+ // Since we're building the 'expected' input out of order we need to do some trickery
+ // to get the locations right.
+ SpancestryCorrector.Correct(expected);
+ expected.FindFirstDescendentSpan().ChangeStart(SourceLocation.Zero);
+
+ // We make the caller pass a start location so we can verify that nothing has gone awry.
+ Assert.Equal(expectedStart, expectedMarkup.Start);
+
+ ParseBlockTest(prefix + markup + suffix, expected);
+ }
+
+ private void NamespaceImportTest(string content, string expectedNS, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.None, SourceLocation? location = null)
+ {
+ ParseBlockTest(content,
+ new DirectiveBlock(
+ Factory.Code(content)
+ .AsNamespaceImport(expectedNS)
+ .Accepts(acceptedCharacters)));
+ }
+
+ private static StatementBlock CreateStatementBlock(MarkupBlock block)
+ {
+ var factory = new SpanFactory();
+ return new StatementBlock(
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ block,
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs
new file mode 100644
index 0000000000..23cda39e22
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs
@@ -0,0 +1,1965 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpDirectivesTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void DirectiveDescriptor_FileScopedMultipleOccurring_CanHaveDuplicates()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = DirectiveUsage.FileScopedMultipleOccurring;
+ builder.AddTypeToken();
+ });
+
+ // Act & Assert
+ ParseDocumentTest(
+@"@custom System.Text.Encoding.ASCIIEncoding
+@custom System.Text.Encoding.UTF8Encoding",
+ new[] { descriptor },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.UTF8Encoding", markup: false).AsDirectiveToken(descriptor.Tokens[0])),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_FileScopedSinglyOccurring_ErrorsIfDuplicate()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = DirectiveUsage.FileScopedSinglyOccurring;
+ builder.AddTypeToken();
+ });
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DuplicateDirective(
+ new SourceSpan(new SourceLocation(42 + Environment.NewLine.Length, 1, 0), 7), "custom"));
+
+ // Act & Assert
+ ParseDocumentTest(
+@"@custom System.Text.Encoding.ASCIIEncoding
+@custom System.Text.Encoding.UTF8Encoding",
+ new[] { descriptor },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.UTF8Encoding", markup: false).AsDirectiveToken(descriptor.Tokens[0])),
+ Factory.EmptyHtml()));
+ }
+
+ [Theory]
+ [InlineData(DirectiveUsage.FileScopedSinglyOccurring)]
+ [InlineData(DirectiveUsage.FileScopedMultipleOccurring)]
+ public void DirectiveDescriptor_FileScoped_CanBeBeneathOtherDirectives(DirectiveUsage directiveUsage)
+ {
+ // Arrange
+ var customDescriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = directiveUsage;
+ builder.AddTypeToken();
+ });
+ var somethingDescriptor = DirectiveDescriptor.CreateDirective(
+ "something",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = directiveUsage;
+ builder.AddMemberToken();
+ });
+
+ // Act & Assert
+ ParseDocumentTest(
+@"@custom System.Text.Encoding.ASCIIEncoding
+@something Else",
+ new[] { customDescriptor, somethingDescriptor },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(customDescriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(customDescriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(somethingDescriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("something").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Else", markup: false).AsDirectiveToken(somethingDescriptor.Tokens[0])),
+ Factory.EmptyHtml()));
+ }
+
+ [Theory]
+ [InlineData(DirectiveUsage.FileScopedSinglyOccurring)]
+ [InlineData(DirectiveUsage.FileScopedMultipleOccurring)]
+ public void DirectiveDescriptor_FileScoped_CanBeBeneathOtherWhiteSpaceCommentsAndDirectives(DirectiveUsage directiveUsage)
+ {
+ // Arrange
+ var customDescriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = directiveUsage;
+ builder.AddTypeToken();
+ });
+ var somethingDescriptor = DirectiveDescriptor.CreateDirective(
+ "something",
+ DirectiveKind.SingleLine,
+ builder =>
+ {
+ builder.Usage = directiveUsage;
+ builder.AddMemberToken();
+ });
+
+ // Act & Assert
+ ParseDocumentTest(
+@"@* There are two directives beneath this *@
+@custom System.Text.Encoding.ASCIIEncoding
+
+@something Else
+
+<p>This is extra</p>",
+ new[] { customDescriptor, somethingDescriptor },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(" There are two directives beneath this ", HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine),
+ new DirectiveBlock(new DirectiveChunkGenerator(customDescriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(customDescriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.Markup(Environment.NewLine),
+ new DirectiveBlock(new DirectiveChunkGenerator(somethingDescriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("something").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Else", markup: false).AsDirectiveToken(somethingDescriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.Markup(Environment.NewLine),
+ BlockFactory.MarkupTagBlock("<p>"),
+ Factory.Markup("This is extra"),
+ BlockFactory.MarkupTagBlock("</p>")));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_TokensMustBeSeparatedBySpace()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken().AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveTokensMustBeSeparatedByWhitespace(
+ new SourceSpan(new SourceLocation(17, 0, 17), 9), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"string1\"\"string2\"",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"string1\"", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_CanHandleEOFIncompleteNamespaceTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace(
+ new SourceSpan(new SourceLocation(8, 0, 8), 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System.",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_CanHandleEOFInvalidNamespaceTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace(
+ new SourceSpan(new SourceLocation(8, 0, 8), 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System<",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+ [Fact]
+ public void DirectiveDescriptor_CanHandleIncompleteNamespaceTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace(
+ new SourceSpan(new SourceLocation(8, 0, 8), 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System." + Environment.NewLine,
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_CanHandleInvalidNamespaceTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsNamespace(
+ new SourceSpan(new SourceLocation(8, 0, 8), 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System<" + Environment.NewLine,
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void ExtensibleDirectiveDoesNotErorrIfNotAtStartOfLineBecauseOfWhitespace()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(Environment.NewLine + " @custom System.Text.Encoding.ASCIIEncoding",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.Code(Environment.NewLine + " ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void BuiltInDirectiveDoesNotErorrIfNotAtStartOfLineBecauseOfWhitespace()
+ {
+ // Act & Assert
+ ParseCodeBlockTest(Environment.NewLine + " @addTagHelper \"*, Foo\"",
+ Enumerable.Empty<DirectiveDescriptor>(),
+ new DirectiveBlock(
+ Factory.Code(Environment.NewLine + " ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"*, Foo\"")
+ .AsAddTagHelper(
+ "\"*, Foo\"",
+ "*, Foo",
+ "*",
+ "Foo")));
+ }
+
+ [Fact]
+ public void BuiltInDirectiveErrorsIfNotAtStartOfLine()
+ {
+ // Act & Assert
+ ParseCodeBlockTest("{ @addTagHelper \"*, Foo\"" + Environment.NewLine + "}",
+ Enumerable.Empty<DirectiveDescriptor>(),
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null, atEndOfSpan: false),
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"*, Foo\"")
+ .AsAddTagHelper(
+ "\"*, Foo\"",
+ "*, Foo",
+ "*",
+ "Foo",
+ RazorDiagnosticFactory.CreateParsing_DirectiveMustAppearAtStartOfLine(
+ new SourceSpan(new SourceLocation(4, 0, 4), 12), "addTagHelper"))),
+ Factory.Code(Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ExtensibleDirectiveErrorsIfNotAtStartOfLine()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveMustAppearAtStartOfLine(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 6), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "{ @custom System.Text.Encoding.ASCIIEncoding" + Environment.NewLine + "}",
+ new[] { descriptor },
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null, atEndOfSpan: false),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsTypeTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System.Text.Encoding.ASCIIEncoding",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsMemberTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddMemberToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom Some_Member",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void Parser_ParsesNamespaceDirectiveToken_WithSingleSegment()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom BaseNamespace",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "BaseNamespace", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void Parser_ParsesNamespaceDirectiveToken_WithMultipleSegments()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddNamespaceToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom BaseNamespace.Foo.Bar",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "BaseNamespace.Foo.Bar", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsStringTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"AString\"",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_StringToken_ParserErrorForUnquotedValue()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom AString",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_StringToken_ParserErrorForNonStringValue()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 1), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom {foo?}",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_StringToken_ParserErrorForSingleQuotedValue()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 9), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom 'AString'",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_StringToken_ParserErrorForPartialQuotedValue()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsQuotedStringLiteral(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 7), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom AString\"",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsMultipleTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken().AddMemberToken().AddStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System.Text.Encoding.ASCIIEncoding Some_Member \"AString\"",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[1]),
+
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false).AsDirectiveToken(descriptor.Tokens[2])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsRazorBlocks()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.RazorBlock,
+ b => b.AddStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"Header\" { <p>F{o}o</p> }",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"Header\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{")
+ .AutoCompleteWith(null, atEndOfSpan: true)
+ .Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("F", "{", "o", "}", "o"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_UnderstandsCodeBlocks()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.CodeBlock,
+ b => b.AddStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"Name\" { foo(); bar(); }",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"Name\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{")
+ .AutoCompleteWith(null, atEndOfSpan: true)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" foo(); bar(); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_AllowsWhiteSpaceAroundTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken().AddMemberToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom System.Text.Encoding.ASCIIEncoding Some_Member ",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[1]),
+
+ Factory.Span(SpanKindInternal.None, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_ErrorsForInvalidMemberTokens()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddMemberToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 1), "custom"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom -Some_Member",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_NoErrorsSemicolonAfterDirective()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"hello\" ; ",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.None, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.MetaCode(";").Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Theory]
+ [InlineData("string?")]
+ [InlineData("string?[]")]
+ [InlineData("global::System.Int32?")]
+ [InlineData("KeyValuePair<string, string>?")]
+ [InlineData("KeyValuePair<string, string>?[]")]
+ [InlineData("global::System.Collections.Generic.KeyValuePair<string, string>?[]")]
+ public void DirectiveDescriptor_AllowsNullableTypes(string expectedType)
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ $"@custom {expectedType}",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, expectedType, markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Theory]
+ [InlineData("(bool, int)")]
+ [InlineData("(int aa, string bb)?")]
+ [InlineData("( int? q , bool w )")]
+ [InlineData("( int ? q, bool ?w ,(long ? [])) ?")]
+ [InlineData("(List<(int, string)?> aa, string bb)")]
+ [InlineData("(string ss, (int u, List<(string, int)> k, (Char c, bool b, List<int> l)), global::System.Int32[] a)")]
+ public void DirectiveDescriptor_AllowsTupleTypes(string expectedType)
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ $"@custom {expectedType}",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, expectedType, markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_AllowsTupleTypes_IgnoresTrailingWhitespace()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ $"@custom (bool, int?) ",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "(bool, int?)", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.None, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_ErrorsExtraContentAfterDirective()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 7), "custom", "line break"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"hello\" \"world\"",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+
+ Factory.Span(SpanKindInternal.None, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_ErrorsWhenExtraContentBeforeBlockStart()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.CodeBlock,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 5), "custom", "{"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"Hello\" World { foo(); bar(); }",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_ErrorsWhenEOFBeforeDirectiveBlockStart()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.CodeBlock,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 1), "custom", "{"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"Hello\"",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void DirectiveDescriptor_ErrorsWhenMissingEndBrace()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.CodeBlock,
+ b => b.AddStringToken());
+ var chunkGenerator = new DirectiveChunkGenerator(descriptor);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 1), "custom", "}", "{"));
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"Hello\" {",
+ new[] { descriptor },
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{")
+ .AutoCompleteWith("}", atEndOfSpan: true)
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_DuplicatesCauseError()
+ {
+ // Arrange
+ var expectedDiagnostic = RazorDiagnosticFactory.CreateParsing_DuplicateDirective(
+ new SourceSpan(null, 22 + Environment.NewLine.Length, 1, 0, 16), "tagHelperPrefix");
+
+ // Act
+ var document = ParseDocument(
+@"@tagHelperPrefix ""th:""
+@tagHelperPrefix ""th""",
+ directives: null,
+ designTime: false);
+
+ // Assert
+ var directive = document.Root.Children.OfType<Block>().Last();
+ var erroredSpan = (Span)directive.Children.Last();
+ var chunkGenerator = Assert.IsType<TagHelperPrefixDirectiveChunkGenerator>(erroredSpan.ChunkGenerator);
+ var diagnostic = Assert.Single(chunkGenerator.Diagnostics);
+ Assert.Equal(expectedDiagnostic, diagnostic);
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_NoValueSucceeds()
+ {
+ ParseBlockTest("@tagHelperPrefix \"\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\"")
+ .AsTagHelperPrefixDirective("\"\"", string.Empty)));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_Succeeds()
+ {
+ ParseBlockTest("@tagHelperPrefix Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo")
+ .AsTagHelperPrefixDirective("Foo", "Foo")));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_WithQuotes_Succeeds()
+ {
+ ParseBlockTest("@tagHelperPrefix \"Foo\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo\"")
+ .AsTagHelperPrefixDirective("\"Foo\"", "Foo")));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_RequiresValue()
+ {
+ // Arrange
+ var expectedError = RazorDiagnosticFactory.CreateParsing_DirectiveMustHaveValue(
+ new SourceSpan(filePath: null, absoluteIndex: 1, lineIndex: 0, characterIndex: 1, length: 15), SyntaxConstants.CSharp.TagHelperPrefixKeyword);
+
+ // Act & Assert
+ ParseBlockTest("@tagHelperPrefix ",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsTagHelperPrefixDirective(string.Empty, string.Empty, expectedError)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_StartQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 4), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 4), SyntaxConstants.CSharp.TagHelperPrefixKeyword, '"', "\"Foo"),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@tagHelperPrefix \"Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo")
+ .AsTagHelperPrefixDirective("\"Foo", "\"Foo", expectedErrors)));
+ }
+
+ [Fact]
+ public void TagHelperPrefixDirective_EndQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 23, lineIndex: 0, characterIndex: 23, length: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 7), SyntaxConstants.CSharp.TagHelperPrefixKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 7), SyntaxConstants.CSharp.TagHelperPrefixKeyword, ' ', "Foo \""),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@tagHelperPrefix Foo \"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.TagHelperPrefixKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo \"")
+ .AsTagHelperPrefixDirective("Foo \"", "Foo \"", expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_NoValue_Invalid()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(18, 0, 18), contentLength: 1), string.Empty)
+ };
+
+ ParseBlockTest("@removeTagHelper \"\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\"")
+ .AsRemoveTagHelper(
+ "\"\"",
+ string.Empty,
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_InvalidLookupText_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 3), "Foo")
+ };
+
+ ParseBlockTest("@removeTagHelper Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo")
+ .AsRemoveTagHelper(
+ "Foo",
+ "Foo",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_SingleQuotes_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 8), "'*, Foo'")
+ };
+
+ ParseBlockTest("@removeTagHelper '*, Foo'",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("'*, Foo'")
+ .AsRemoveTagHelper(
+ "'*, Foo'",
+ "'*, Foo'",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_WithQuotes_InvalidLookupText_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(18, 0, 18), contentLength: 3), "Foo")
+ };
+
+ ParseBlockTest("@removeTagHelper \"Foo\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo\"")
+ .AsRemoveTagHelper(
+ "\"Foo\"",
+ "Foo",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_SupportsSpaces()
+ {
+ ParseBlockTest("@removeTagHelper Foo, Bar ",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo, Bar ")
+ .AsRemoveTagHelper(
+ "Foo, Bar",
+ "Foo, Bar",
+ "Foo",
+ "Bar")
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_RequiresValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_DirectiveMustHaveValue(
+ new SourceSpan(filePath: null, absoluteIndex: 1, lineIndex: 0, characterIndex: 1, length: 15), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 1), string.Empty),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@removeTagHelper ",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsRemoveTagHelper(string.Empty, string.Empty, errors: expectedErrors)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_StartQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 4), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 4), "\"Foo"),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@removeTagHelper \"Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo")
+ .AsRemoveTagHelper("\"Foo", "\"Foo", errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void RemoveTagHelperDirective_EndQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(absoluteIndex: 20, lineIndex: 0, characterIndex: 20), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 4), SyntaxConstants.CSharp.RemoveTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 4), "Foo\""),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@removeTagHelper Foo\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo\"")
+ .AsRemoveTagHelper("Foo\"", "Foo\"", errors: expectedErrors)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_NoValue_Invalid()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 1), string.Empty),
+ };
+
+ ParseBlockTest("@addTagHelper \"\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\"")
+ .AsAddTagHelper(
+ "\"\"",
+ string.Empty,
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_InvalidLookupText_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 3), "Foo"),
+ };
+
+ ParseBlockTest("@addTagHelper Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo")
+ .AsAddTagHelper(
+ "Foo",
+ "Foo",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_WithQuotes_InvalidLookupText_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 3), "Foo")
+ };
+
+ ParseBlockTest("@addTagHelper \"Foo\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo\"")
+ .AsAddTagHelper(
+ "\"Foo\"",
+ "Foo",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_SingleQuotes_AddsError()
+ {
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 8), "'*, Foo'")
+ };
+
+ ParseBlockTest("@addTagHelper '*, Foo'",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("'*, Foo'")
+ .AsAddTagHelper(
+ "'*, Foo'",
+ "'*, Foo'",
+ errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_SupportsSpaces()
+ {
+ ParseBlockTest("@addTagHelper Foo, Bar ",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo, Bar ")
+ .AsAddTagHelper(
+ "Foo, Bar",
+ "Foo, Bar",
+ "Foo",
+ "Bar")
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_RequiresValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_DirectiveMustHaveValue(
+ new SourceSpan(filePath: null, absoluteIndex: 1, lineIndex: 0, characterIndex: 1, length: 12), SyntaxConstants.CSharp.AddTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 1), string.Empty),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@addTagHelper ",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsAddTagHelper(string.Empty, string.Empty, errors: expectedErrors)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_StartQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 14, lineIndex: 0, characterIndex: 14, length: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 14, lineIndex: 0, characterIndex: 14, length: 4), SyntaxConstants.CSharp.AddTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 4), "\"Foo"),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@addTagHelper \"Foo",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"Foo")
+ .AsAddTagHelper("\"Foo", "\"Foo", errors: expectedErrors)));
+ }
+
+ [Fact]
+ public void AddTagHelperDirective_EndQuoteRequiresDoubleQuotesAroundValue()
+ {
+ // Arrange
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 1)),
+ RazorDiagnosticFactory.CreateParsing_IncompleteQuotesAroundDirective(
+ new SourceSpan(filePath: null, absoluteIndex: 14, lineIndex: 0, characterIndex: 14, length: 4), SyntaxConstants.CSharp.AddTagHelperKeyword),
+ RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 4), "Foo\""),
+ };
+
+ // Act & Assert
+ ParseBlockTest("@addTagHelper Foo\"",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory
+ .MetaCode(SyntaxConstants.CSharp.AddTagHelperKeyword)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory
+ .Span(SpanKindInternal.Markup, " ", markup: false)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Foo\"")
+ .AsAddTagHelper("Foo\"", "Foo\"", errors: expectedErrors)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)));
+ }
+
+ [Fact]
+ public void InheritsDirectiveSupportsArrays()
+ {
+ ParseDocumentTest(
+ "@inherits string[[]][]",
+ new[] { InheritsDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(InheritsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "string[[]][]", markup: false).AsDirectiveToken(InheritsDirective.Directive.Tokens.First())),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void InheritsDirectiveSupportsNestedGenerics()
+ {
+ ParseDocumentTest(
+ "@inherits System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>",
+ new[] { InheritsDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(InheritsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>", markup: false)
+ .AsDirectiveToken(InheritsDirective.Directive.Tokens.First())),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void InheritsDirectiveSupportsTypeKeywords()
+ {
+ ParseDocumentTest(
+ "@inherits string",
+ new[] { InheritsDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(InheritsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "string", markup: false)
+ .AsDirectiveToken(InheritsDirective.Directive.Tokens.First())),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void Parse_FunctionsDirective()
+ {
+ ParseCodeBlockTest(
+ "@functions { foo(); bar(); }",
+ new[] { FunctionsDirective.Directive, },
+ new DirectiveBlock(new DirectiveChunkGenerator(FunctionsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" foo(); bar(); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void EmptyFunctionsDirective()
+ {
+ ParseCodeBlockTest(
+ "@functions { }",
+ new[] { FunctionsDirective.Directive, },
+ new DirectiveBlock(new DirectiveChunkGenerator(FunctionsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void Parse_SectionDirective()
+ {
+ ParseCodeBlockTest(
+ "@section Header { <p>F{o}o</p> }",
+ new[] { SectionDirective.Directive, },
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier)
+ .AsDirectiveToken(SectionDirective.Directive.Tokens.First()),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("F", "{", "o", "}", "o"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}")
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void OptionalDirectiveTokens_AreSkipped()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom ",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)));
+ }
+
+ [Fact]
+ public void OptionalDirectiveTokens_WithSimpleTokens_AreParsed()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"simple-value\"",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"simple-value\"", markup: false)
+ .AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void OptionalDirectiveTokens_WithBraces_AreParsed()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"{formaction}?/{id}?\"",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"{formaction}?/{id}?\"", markup: false)
+ .AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void OptionalDirectiveTokens_WithMultipleOptionalTokens_AreParsed()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "custom",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalStringToken().AddOptionalTypeToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@custom \"{formaction}?/{id}?\" System.String",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "\"{formaction}?/{id}?\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "System.String", markup: false).AsDirectiveToken(descriptor.Tokens.Last())));
+ }
+
+ [Fact]
+ public void OptionalMemberTokens_WithMissingMember_IsParsed()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "TestDirective",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalMemberToken().AddOptionalStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@TestDirective ",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("TestDirective").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, string.Empty, CSharpSymbolType.Unknown)
+ .AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void OptionalMemberTokens_WithMemberSpecified_IsParsed()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "TestDirective",
+ DirectiveKind.SingleLine,
+ b => b.AddOptionalMemberToken().AddOptionalStringToken());
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@TestDirective PropertyName",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("TestDirective").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "PropertyName", markup: false).AsDirectiveToken(descriptor.Tokens[0])));
+ }
+
+ [Fact]
+ public void Directives_CanUseReservedWord_Class()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "class",
+ DirectiveKind.SingleLine);
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@class",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("class").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void Directives_CanUseReservedWord_Namespace()
+ {
+ // Arrange
+ var descriptor = DirectiveDescriptor.CreateDirective(
+ "namespace",
+ DirectiveKind.SingleLine);
+
+ // Act & Assert
+ ParseCodeBlockTest(
+ "@namespace",
+ new[] { descriptor },
+ new DirectiveBlock(
+ new DirectiveChunkGenerator(descriptor),
+ Factory.CodeTransition(),
+ Factory.MetaCode("namespace").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ public static TheoryData InvalidTagHelperPrefixData
+ {
+ get
+ {
+ var directiveLocation = new SourceLocation(1, 2, 3);
+
+ RazorDiagnostic InvalidPrefixError(int length, char character, string prefix)
+ {
+ return RazorDiagnosticFactory.CreateParsing_InvalidTagHelperPrefixValue(
+ new SourceSpan(directiveLocation, length), SyntaxConstants.CSharp.TagHelperPrefixKeyword, character, prefix);
+ }
+
+ return new TheoryData<string, SourceLocation, IEnumerable<RazorDiagnostic>>
+ {
+ {
+ "th ",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(3, ' ', "th "),
+ }
+ },
+ {
+ "th\t",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(3, '\t', "th\t"),
+ }
+ },
+ {
+ "th" + Environment.NewLine,
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(2 + Environment.NewLine.Length, Environment.NewLine[0], "th" + Environment.NewLine),
+ }
+ },
+ {
+ " th ",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(4, ' ', " th "),
+ }
+ },
+ {
+ "@",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(1, '@', "@"),
+ }
+ },
+ {
+ "t@h",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(3, '@', "t@h"),
+ }
+ },
+ {
+ "!",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(1, '!', "!"),
+ }
+ },
+ {
+ "!th",
+ directiveLocation,
+ new[]
+ {
+ InvalidPrefixError(3, '!', "!th"),
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(InvalidTagHelperPrefixData))]
+ public void ValidateTagHelperPrefix_ValidatesPrefix(
+ string directiveText,
+ SourceLocation directiveLocation,
+ object expectedErrors)
+ {
+ // Arrange
+ var expectedDiagnostics = (IEnumerable<RazorDiagnostic>)expectedErrors;
+ var source = TestRazorSourceDocument.Create();
+ var options = RazorParserOptions.CreateDefault();
+ var context = new ParserContext(source, options);
+
+ var parser = new CSharpCodeParser(context);
+ var diagnostics = new List<RazorDiagnostic>();
+
+ // Act
+ parser.ValidateTagHelperPrefix(directiveText, directiveLocation, diagnostics);
+
+ // Assert
+ Assert.Equal(expectedDiagnostics, diagnostics);
+ }
+
+ [Theory]
+ [InlineData("foo,assemblyName", 4)]
+ [InlineData("foo, assemblyName", 5)]
+ [InlineData(" foo, assemblyName", 8)]
+ [InlineData(" foo , assemblyName", 11)]
+ [InlineData("foo, assemblyName", 8)]
+ [InlineData(" foo , assemblyName ", 14)]
+ public void ParseAddOrRemoveDirective_CalculatesAssemblyLocationInLookupText(string text, int assemblyLocation)
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+ var options = RazorParserOptions.CreateDefault();
+ var context = new ParserContext(source, options);
+
+ var parser = new CSharpCodeParser(context);
+
+ var directive = new CSharpCodeParser.ParsedDirective()
+ {
+ DirectiveText = text,
+ };
+
+ var diagnostics = new List<RazorDiagnostic>();
+ var expected = new SourceLocation(assemblyLocation, 0, assemblyLocation);
+
+ // Act
+ var result = parser.ParseAddOrRemoveDirective(directive, SourceLocation.Zero, diagnostics);
+
+ // Assert
+ Assert.Empty(diagnostics);
+ Assert.Equal("foo", result.TypePattern);
+ Assert.Equal("assemblyName", result.AssemblyName);
+ }
+
+ [Theory]
+ [InlineData("", 1)]
+ [InlineData("*,", 2)]
+ [InlineData("?,", 2)]
+ [InlineData(",", 1)]
+ [InlineData(",,,", 3)]
+ [InlineData("First, ", 7)]
+ [InlineData("First , ", 8)]
+ [InlineData(" ,Second", 8)]
+ [InlineData(" , Second", 9)]
+ [InlineData("SomeType,", 9)]
+ [InlineData("SomeAssembly", 12)]
+ [InlineData("First,Second,Third", 18)]
+ public void ParseAddOrRemoveDirective_CreatesErrorIfInvalidLookupText_DoesNotThrow(string directiveText, int errorLength)
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+ var options = RazorParserOptions.CreateDefault();
+ var context = new ParserContext(source, options);
+
+ var parser = new CSharpCodeParser(context);
+
+ var directive = new CSharpCodeParser.ParsedDirective()
+ {
+ DirectiveText = directiveText
+ };
+
+ var diagnostics = new List<RazorDiagnostic>();
+ var expectedError = RazorDiagnosticFactory.CreateParsing_InvalidTagHelperLookupText(
+ new SourceSpan(new SourceLocation(1, 2, 3), errorLength), directiveText);
+
+ // Act
+ var result = parser.ParseAddOrRemoveDirective(directive, new SourceLocation(1, 2, 3), diagnostics);
+
+ // Assert
+ Assert.Same(directive, result);
+
+ var error = Assert.Single(diagnostics);
+ Assert.Equal(expectedError, error);
+ }
+
+ internal virtual void ParseCodeBlockTest(
+ string document,
+ IEnumerable<DirectiveDescriptor> descriptors,
+ Block expected,
+ params RazorDiagnostic[] expectedErrors)
+ {
+ var result = ParseCodeBlock(RazorLanguageVersion.Latest, document, descriptors, designTime: false);
+
+ EvaluateResults(result, expected, expectedErrors);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpErrorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpErrorTest.cs
new file mode 100644
index 0000000000..4d792c1a31
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpErrorTest.cs
@@ -0,0 +1,654 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpErrorTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void ParseBlockHandlesQuotesAfterTransition()
+ {
+ ParseBlockTest("@\"",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1),
+ "\""));
+ }
+
+ [Fact]
+ public void ParseBlockWithHelperDirectiveProducesError()
+ {
+ ParseBlockTest("@helper fooHelper { }",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("helper")
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_HelperDirectiveNotAvailable(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 6)));
+ }
+
+ [Fact]
+ public void ParseBlockWithNestedCodeBlockProducesError()
+ {
+ ParseBlockTest("@if { @{} }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if { ")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.Any),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.Any)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedNestedCodeBlock(
+ new SourceSpan(new SourceLocation(7, 0, 7), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockCapturesWhitespaceToEndOfLineInInvalidUsingStatementAndTreatsAsFileCode()
+ {
+ ParseBlockTest("using " + Environment.NewLine
+ + Environment.NewLine,
+ new StatementBlock(
+ Factory.Code("using " + Environment.NewLine).AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockMethodOutputsOpenCurlyAsCodeSpanIfEofFoundAfterOpenCurlyBrace()
+ {
+ ParseBlockTest("{",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" })
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockMethodOutputsZeroLengthCodeSpanIfStatementBlockEmpty()
+ {
+ ParseBlockTest("{}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockMethodProducesErrorIfNewlineFollowsTransition()
+ {
+ ParseBlockTest("@" + Environment.NewLine,
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), Environment.NewLine.Length)));
+ }
+
+ [Fact]
+ public void ParseBlockMethodProducesErrorIfWhitespaceBetweenTransitionAndBlockStartInEmbeddedExpression()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " @ {}" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Code(" {}" + Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(6 + Environment.NewLine.Length, 1, 5), contentLength: 3)));
+ }
+
+ [Fact]
+ public void ParseBlockMethodProducesErrorIfEOFAfterTransitionInEmbeddedExpression()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " @",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith("}"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.EmptyCSharp().AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(6 + Environment.NewLine.Length, 1, 5), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockMethodParsesNothingIfFirstCharacterIsNotIdentifierStartOrParenOrBrace()
+ {
+ ParseBlockTest("@!!!",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1),
+ "!"));
+ }
+
+ [Fact]
+ public void ParseBlockShouldReportErrorAndTerminateAtEOFIfIfParenInExplicitExpressionUnclosed()
+ {
+ ParseBlockTest("(foo bar" + Environment.NewLine
+ + "baz",
+ new ExpressionBlock(
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"foo bar{Environment.NewLine}baz").AsExpression()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_ExplicitExpression, ")", "("));
+ }
+
+ [Fact]
+ public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfIfParenInExplicitExpressionUnclosed()
+ {
+ ParseBlockTest("(foo bar" + Environment.NewLine
+ + "<html>" + Environment.NewLine
+ + "baz" + Environment.NewLine
+ + "</html",
+ new ExpressionBlock(
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"foo bar{Environment.NewLine}").AsExpression()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_ExplicitExpression, ")", "("));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyHandlesInCorrectTransitionsIfImplicitExpressionParensUnclosed()
+ {
+ ParseBlockTest("Href(" + Environment.NewLine
+ + "<h1>@Html.Foo(Bar);</h1>" + Environment.NewLine,
+ new ExpressionBlock(
+ Factory.Code("Href(" + Environment.NewLine)
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ // Test for fix to Dev10 884975 - Incorrect Error Messaging
+ public void ParseBlockShouldReportErrorAndTerminateAtEOFIfParenInImplicitExpressionUnclosed()
+ {
+ ParseBlockTest("Foo(Bar(Baz)" + Environment.NewLine
+ + "Biz" + Environment.NewLine
+ + "Boz",
+ new ExpressionBlock(
+ Factory.Code($"Foo(Bar(Baz){Environment.NewLine}Biz{Environment.NewLine}Boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(3, 0, 3), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ // Test for fix to Dev10 884975 - Incorrect Error Messaging
+ public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfParenInImplicitExpressionUnclosed()
+ {
+ ParseBlockTest("Foo(Bar(Baz)" + Environment.NewLine
+ + "Biz" + Environment.NewLine
+ + "<html>" + Environment.NewLine
+ + "Boz" + Environment.NewLine
+ + "</html>",
+ new ExpressionBlock(
+ Factory.Code($"Foo(Bar(Baz){Environment.NewLine}Biz{Environment.NewLine}")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(3, 0, 3), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ // Test for fix to Dev10 884975 - Incorrect Error Messaging
+ public void ParseBlockShouldReportErrorAndTerminateAtEOFIfBracketInImplicitExpressionUnclosed()
+ {
+ ParseBlockTest("Foo[Bar[Baz]" + Environment.NewLine
+ + "Biz" + Environment.NewLine
+ + "Boz",
+ new ExpressionBlock(
+ Factory.Code($"Foo[Bar[Baz]{Environment.NewLine}Biz{Environment.NewLine}Boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(3, 0, 3), contentLength: 1), "[", "]"));
+ }
+
+ [Fact]
+ // Test for fix to Dev10 884975 - Incorrect Error Messaging
+ public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfBracketInImplicitExpressionUnclosed()
+ {
+ ParseBlockTest("Foo[Bar[Baz]" + Environment.NewLine
+ + "Biz" + Environment.NewLine
+ + "<b>" + Environment.NewLine
+ + "Boz" + Environment.NewLine
+ + "</b>",
+ new ExpressionBlock(
+ Factory.Code($"Foo[Bar[Baz]{Environment.NewLine}Biz{Environment.NewLine}")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(3, 0, 3), contentLength: 1), "[", "]"));
+ }
+
+ // Simple EOF handling errors:
+ [Fact]
+ public void ParseBlockReportsErrorIfExplicitCodeBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("{ var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; if(foo != null) { bar(); } ")
+ .AsStatement()
+ .AutoCompleteWith("}")),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfClassBlockUnterminatedAtEOF()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(FunctionsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 1), "functions", "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "functions { var foo = bar; if(foo != null) { bar(); } ",
+ new[] { FunctionsDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; if(foo != null) { bar(); } ").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfIfBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("if");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfElseBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("if(foo) { baz(); } else { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("if(foo) { baz(); } else { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(19, 0, 19), contentLength: 1), "else", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfElseIfBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("if(foo) { baz(); } else if { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("if(foo) { baz(); } else if { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(19, 0, 19), contentLength: 1), "else if", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfDoBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("do { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("do { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "do", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfTryBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("try { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("try { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "try", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfCatchBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("try { baz(); } catch(Foo) { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("try { baz(); } catch(Foo) { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 1), "catch", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfFinallyBlockUnterminatedAtEOF()
+ {
+ ParseBlockTest("try { baz(); } finally { var foo = bar; if(foo != null) { bar(); } ",
+ new StatementBlock(
+ Factory.Code("try { baz(); } finally { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(15, 0, 15), contentLength: 1), "finally", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfForBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("for");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfForeachBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("foreach");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfWhileBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("while");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfSwitchBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("switch");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfLockBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("lock");
+ }
+
+ [Fact]
+ public void ParseBlockReportsErrorIfUsingBlockUnterminatedAtEOF()
+ {
+ RunUnterminatedSimpleKeywordBlock("using");
+ }
+
+ [Fact]
+ public void ParseBlockRequiresControlFlowStatementsToHaveBraces()
+ {
+ var expectedMessage = Resources.FormatParseError_SingleLine_ControlFlowStatements_Not_Allowed("{", "<");
+ ParseBlockTest("if(foo) <p>Bar</p> else if(bar) <p>Baz</p> else <p>Boz</p>",
+ new StatementBlock(
+ Factory.Code("if(foo) ").AsStatement(),
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Bar"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("else if(bar) ").AsStatement(),
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Baz"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("else ").AsStatement(),
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Boz"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 1), "{", "<"),
+ RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed(
+ new SourceSpan(new SourceLocation(32, 0, 32), contentLength: 1), "{", "<"),
+ RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed(
+ new SourceSpan(new SourceLocation(48, 0, 48), contentLength: 1), "{", "<"));
+ }
+
+ [Fact]
+ public void ParseBlockIncludesUnexpectedCharacterInSingleStatementControlFlowStatementError()
+ {
+ ParseBlockTest("if(foo)) { var bar = foo; }",
+ new StatementBlock(
+ Factory.Code("if(foo)) { var bar = foo; }").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_SingleLineControlFlowStatementsNotAllowed(
+ new SourceSpan(new SourceLocation(7, 0, 7), contentLength: 1), "{", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockOutputsErrorIfAtSignFollowedByLessThanSignAtStatementStart()
+ {
+ ParseBlockTest("if(foo) { @<p>Bar</p> }",
+ new StatementBlock(
+ Factory.Code("if(foo) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Bar"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_AtInCodeMustBeFollowedByColonParenOrIdentifierStart(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesIfBlockAtEOLWhenRecoveringFromMissingCloseParen()
+ {
+ ParseBlockTest("if(foo bar" + Environment.NewLine
+ + "baz",
+ new StatementBlock(
+ Factory.Code("if(foo bar" + Environment.NewLine).AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesForeachBlockAtEOLWhenRecoveringFromMissingCloseParen()
+ {
+ ParseBlockTest("foreach(foo bar" + Environment.NewLine
+ + "baz",
+ new StatementBlock(
+ Factory.Code("foreach(foo bar" + Environment.NewLine).AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(7, 0, 7), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesWhileClauseInDoStatementAtEOLWhenRecoveringFromMissingCloseParen()
+ {
+ ParseBlockTest("do { } while(foo bar" + Environment.NewLine
+ + "baz",
+ new StatementBlock(
+ Factory.Code("do { } while(foo bar" + Environment.NewLine).AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(12, 0, 12), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesUsingBlockAtEOLWhenRecoveringFromMissingCloseParen()
+ {
+ ParseBlockTest("using(foo bar" + Environment.NewLine
+ + "baz",
+ new StatementBlock(
+ Factory.Code("using(foo bar" + Environment.NewLine).AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(5, 0, 5), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockResumesIfStatementAfterOpenParen()
+ {
+ ParseBlockTest("if(" + Environment.NewLine
+ + "else { <p>Foo</p> }",
+ new StatementBlock(
+ Factory.Code($"if({Environment.NewLine}else {{").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement().Accepts(AcceptedCharactersInternal.None)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesNormalCSharpStringsAtEOLIfEndQuoteMissing()
+ {
+ SingleSpanBlockTest("if(foo) {" + Environment.NewLine
+ + " var p = \"foo bar baz" + Environment.NewLine
+ + ";" + Environment.NewLine
+ + "}",
+ BlockKindInternal.Statement, SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(21 + Environment.NewLine.Length, 1, 12), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesNormalStringAtEndOfFile()
+ {
+ SingleSpanBlockTest("if(foo) { var foo = \"blah blah blah blah blah", BlockKindInternal.Statement, SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(20, 0, 20), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "if", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesVerbatimStringAtEndOfFile()
+ {
+ SingleSpanBlockTest("if(foo) { var foo = @\"blah " + Environment.NewLine
+ + "blah; " + Environment.NewLine
+ + "<p>Foo</p>" + Environment.NewLine
+ + "blah " + Environment.NewLine
+ + "blah",
+ BlockKindInternal.Statement, SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(20, 0, 20), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), "if", "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesMarkupIncorrectyAssumedToBeWithinAStatement()
+ {
+ ParseBlockTest("if(foo) {" + Environment.NewLine
+ + " var foo = \"foo bar baz" + Environment.NewLine
+ + " <p>Foo is @foo</p>" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code($"if(foo) {{{Environment.NewLine} var foo = \"foo bar baz{Environment.NewLine} ").AsStatement(),
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo is "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement()
+ ),
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(new SourceLocation(23 + Environment.NewLine.Length, 1, 14), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyParsesAtSignInDelimitedBlock()
+ {
+ ParseBlockTest("(Request[\"description\"] ?? @photo.Description)",
+ new ExpressionBlock(
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Request[\"description\"] ?? @photo.Description").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyRecoversFromMissingCloseParenInExpressionWithinCode()
+ {
+ ParseBlockTest(@"{string.Format(<html></html>}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("string.Format(")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<html>", AcceptedCharactersInternal.None),
+ BlockFactory.MarkupTagBlock("</html>", AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ expectedErrors: new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 1), "(", ")"),
+ });
+ }
+
+ private void RunUnterminatedSimpleKeywordBlock(string keyword)
+ {
+ SingleSpanBlockTest(
+ keyword + " (foo) { var foo = bar; if(foo != null) { bar(); } ",
+ BlockKindInternal.Statement,
+ SpanKindInternal.Code,
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(SourceLocation.Zero, contentLength: 1), keyword, "}", "{"));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpExplicitExpressionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpExplicitExpressionTest.cs
new file mode 100644
index 0000000000..afc2afa90a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpExplicitExpressionTest.cs
@@ -0,0 +1,139 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpExplicitExpressionTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void ParseBlockShouldOutputZeroLengthCodeSpanIfExplicitExpressionIsEmpty()
+ {
+ ParseBlockTest("@()",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp().AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldOutputZeroLengthCodeSpanIfEOFOccursAfterStartOfExplicitExpression()
+ {
+ ParseBlockTest("@(",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp().AsExpression()
+ ),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1),
+ Resources.BlockName_ExplicitExpression,
+ ")",
+ "("));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptEscapedQuoteInNonVerbatimStrings()
+ {
+ ParseBlockTest("@(\"\\\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\\\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptEscapedQuoteInVerbatimStrings()
+ {
+ ParseBlockTest("@(@\"\"\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("@\"\"\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptMultipleRepeatedEscapedQuoteInVerbatimStrings()
+ {
+ ParseBlockTest("@(@\"\"\"\"\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("@\"\"\"\"\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptMultiLineVerbatimStrings()
+ {
+ ParseBlockTest(@"@(@""" + Environment.NewLine
+ + @"Foo" + Environment.NewLine
+ + @"Bar" + Environment.NewLine
+ + @"Baz" + Environment.NewLine
+ + @""")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"@\"{Environment.NewLine}Foo{Environment.NewLine}Bar{Environment.NewLine}Baz{Environment.NewLine}\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptMultipleEscapedQuotesInNonVerbatimStrings()
+ {
+ ParseBlockTest("@(\"\\\"hello, world\\\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\\\"hello, world\\\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptMultipleEscapedQuotesInVerbatimStrings()
+ {
+ ParseBlockTest("@(@\"\"\"hello, world\"\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("@\"\"\"hello, world\"\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptConsecutiveEscapedQuotesInNonVerbatimStrings()
+ {
+ ParseBlockTest("@(\"\\\"\\\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"\\\"\\\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldAcceptConsecutiveEscapedQuotesInVerbatimStrings()
+ {
+ ParseBlockTest("@(@\"\"\"\"\"\")",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("@\"\"\"\"\"\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpImplicitExpressionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpImplicitExpressionTest.cs
new file mode 100644
index 0000000000..3a013a6ec8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpImplicitExpressionTest.cs
@@ -0,0 +1,282 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpImplicitExpressionTest : CsHtmlCodeParserTestBase
+ {
+ private const string TestExtraKeyword = "model";
+
+ public static TheoryData NullConditionalOperatorData_Bracket
+ {
+ get
+ {
+ var noErrors = new RazorDiagnostic[0];
+ Func<int, RazorDiagnostic[]> missingEndBracketError = (index) =>
+ new RazorDiagnostic[1]
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(index, 0, index), contentLength: 1), "[", "]"),
+ };
+
+ // implicitExpression, expectedImplicitExpression, acceptedCharacters, expectedErrors
+ return new TheoryData<string, string, AcceptedCharactersInternal, RazorDiagnostic[]>
+ {
+ { "val??[", "val", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val??[0", "val", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[", "val?[", AcceptedCharactersInternal.Any, missingEndBracketError(5) },
+ { "val?(", "val", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[more", "val?[more", AcceptedCharactersInternal.Any, missingEndBracketError(5) },
+ { "val?[0]", "val?[0]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[<p>", "val?[", AcceptedCharactersInternal.Any, missingEndBracketError(5) },
+ { "val?[more.<p>", "val?[more.", AcceptedCharactersInternal.Any, missingEndBracketError(5) },
+ { "val??[more<p>", "val", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[-1]?", "val?[-1]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[abc]?[def", "val?[abc]?[def", AcceptedCharactersInternal.Any, missingEndBracketError(11) },
+ { "val?[abc]?[2]", "val?[abc]?[2]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[abc]?.more?[def]", "val?[abc]?.more?[def]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[abc]?.more?.abc", "val?[abc]?.more?.abc", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[null ?? true]", "val?[null ?? true]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ { "val?[abc?.gef?[-1]]", "val?[abc?.gef?[-1]]", AcceptedCharactersInternal.NonWhiteSpace, noErrors },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NullConditionalOperatorData_Bracket))]
+ public void ParseBlockMethodParsesNullConditionalOperatorImplicitExpression_Bracket(
+ string implicitExpresison,
+ string expectedImplicitExpression,
+ object acceptedCharacters,
+ object expectedErrors)
+ {
+ // Act & Assert
+ ImplicitExpressionTest(
+ implicitExpresison,
+ expectedImplicitExpression,
+ (AcceptedCharactersInternal)acceptedCharacters,
+ (RazorDiagnostic[])expectedErrors);
+ }
+
+ public static TheoryData NullConditionalOperatorData_Dot
+ {
+ get
+ {
+ // implicitExpression, expectedImplicitExpression
+ return new TheoryData<string, string>
+ {
+ { "val?", "val" },
+ { "val??", "val" },
+ { "val??more", "val" },
+ { "val?!", "val" },
+ { "val?.", "val?." },
+ { "val??.", "val" },
+ { "val?.(abc)", "val?." },
+ { "val?.<p>", "val?." },
+ { "val?.more", "val?.more" },
+ { "val?.more<p>", "val?.more" },
+ { "val??.more<p>", "val" },
+ { "val?.more(false)?.<p>", "val?.more(false)?." },
+ { "val?.more(false)?.abc", "val?.more(false)?.abc" },
+ { "val?.more(null ?? true)?.abc", "val?.more(null ?? true)?.abc" },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NullConditionalOperatorData_Dot))]
+ public void ParseBlockMethodParsesNullConditionalOperatorImplicitExpression_Dot(
+ string implicitExpresison,
+ string expectedImplicitExpression)
+ {
+ // Act & Assert
+ ImplicitExpressionTest(implicitExpresison, expectedImplicitExpression);
+ }
+
+ [Fact]
+ public void NestedImplicitExpression()
+ {
+ ParseBlockTest("if (true) { @foo }",
+ new StatementBlock(
+ Factory.Code("if (true) { ").AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Code(" }").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockAcceptsNonEnglishCharactersThatAreValidIdentifiers()
+ {
+ ImplicitExpressionTest("हळूँजद॔.", "हळूँजद॔");
+ }
+
+ [Fact]
+ public void ParseBlockOutputsZeroLengthCodeSpanIfInvalidCharacterFollowsTransition()
+ {
+ ParseBlockTest("@/",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1),
+ "/"));
+ }
+
+ [Fact]
+ public void ParseBlockOutputsZeroLengthCodeSpanIfEOFOccursAfterTransition()
+ {
+ ParseBlockTest("@",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsSlashesWithinComplexImplicitExpressions()
+ {
+ ImplicitExpressionTest("DataGridColumn.Template(\"Years of Service\", e => (int)Math.Round((DateTime.Now - dt).TotalDays / 365))");
+ }
+
+ [Fact]
+ public void ParseBlockMethodParsesSingleIdentifierAsImplicitExpression()
+ {
+ ImplicitExpressionTest("foo");
+ }
+
+ [Fact]
+ public void ParseBlockMethodDoesNotAcceptSemicolonIfExpressionTerminatedByWhitespace()
+ {
+ ImplicitExpressionTest("foo ;", "foo");
+ }
+
+ [Fact]
+ public void ParseBlockMethodIgnoresSemicolonAtEndOfSimpleImplicitExpression()
+ {
+ RunTrailingSemicolonTest("foo");
+ }
+
+ [Fact]
+ public void ParseBlockMethodParsesDottedIdentifiersAsImplicitExpression()
+ {
+ ImplicitExpressionTest("foo.bar.baz");
+ }
+
+ [Fact]
+ public void ParseBlockMethodIgnoresSemicolonAtEndOfDottedIdentifiers()
+ {
+ RunTrailingSemicolonTest("foo.bar.baz");
+ }
+
+ [Fact]
+ public void ParseBlockMethodDoesNotIncludeDotAtEOFInImplicitExpression()
+ {
+ ImplicitExpressionTest("foo.bar.", "foo.bar");
+ }
+
+ [Fact]
+ public void ParseBlockMethodDoesNotIncludeDotFollowedByInvalidIdentifierCharacterInImplicitExpression()
+ {
+ ImplicitExpressionTest("foo.bar.0", "foo.bar");
+ ImplicitExpressionTest("foo.bar.</p>", "foo.bar");
+ }
+
+ [Fact]
+ public void ParseBlockMethodDoesNotIncludeSemicolonAfterDot()
+ {
+ ImplicitExpressionTest("foo.bar.;", "foo.bar");
+ }
+
+ [Fact]
+ public void ParseBlockMethodTerminatesAfterIdentifierUnlessFollowedByDotOrParenInImplicitExpression()
+ {
+ ImplicitExpressionTest("foo.bar</p>", "foo.bar");
+ }
+
+ [Fact]
+ public void ParseBlockProperlyParsesParenthesesAndBalancesThemInImplicitExpression()
+ {
+ ImplicitExpressionTest(@"foo().bar(""bi\""z"", 4)(""chained method; call"").baz(@""bo""""z"", '\'', () => { return 4; }, (4+5+new { foo = bar[4] }))");
+ }
+
+ [Fact]
+ public void ParseBlockProperlyParsesBracketsAndBalancesThemInImplicitExpression()
+ {
+ ImplicitExpressionTest(@"foo.bar[4 * (8 + 7)][""fo\""o""].baz");
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionAtHtmlEndTag()
+ {
+ ImplicitExpressionTest("foo().bar.baz</p>zoop", "foo().bar.baz");
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionAtHtmlStartTag()
+ {
+ ImplicitExpressionTest("foo().bar.baz<p>zoop", "foo().bar.baz");
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionBeforeDotIfDotNotFollowedByIdentifierStartCharacter()
+ {
+ ImplicitExpressionTest("foo().bar.baz.42", "foo().bar.baz");
+ }
+
+ [Fact]
+ public void ParseBlockStopsBalancingParenthesesAtEOF()
+ {
+ ImplicitExpressionTest(
+ "foo(()", "foo(()",
+ acceptedCharacters: AcceptedCharactersInternal.Any,
+ errors: RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionIfCloseParenFollowedByAnyWhiteSpace()
+ {
+ ImplicitExpressionTest("foo.bar() (baz)", "foo.bar()");
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionIfIdentifierFollowedByAnyWhiteSpace()
+ {
+ ImplicitExpressionTest("foo .bar() (baz)", "foo");
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesImplicitExpressionAtLastValidPointIfDotFollowedByWhitespace()
+ {
+ ImplicitExpressionTest("foo. bar() (baz)", "foo");
+ }
+
+ [Fact]
+ public void ParseBlockOutputExpressionIfModuleTokenNotFollowedByBrace()
+ {
+ ImplicitExpressionTest("module.foo()");
+ }
+
+ private void RunTrailingSemicolonTest(string expr)
+ {
+ ParseBlockTest(SyntaxConstants.TransitionString + expr + ";",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code(expr)
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpLanguageCharacteristicsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpLanguageCharacteristicsTest.cs
new file mode 100644
index 0000000000..1ab365c98a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpLanguageCharacteristicsTest.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpLanguageCharacteristicsTest
+ {
+ [Fact]
+ public void GetSample_RightShiftAssign_ReturnsCorrectSymbol()
+ {
+ // Arrange & Act
+ var symbol = CSharpLanguageCharacteristics.Instance.GetSample(CSharpSymbolType.RightShiftAssign);
+
+ // Assert
+ Assert.Equal(">>=", symbol);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpNestedStatementsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpNestedStatementsTest.cs
new file mode 100644
index 0000000000..9cc91b0a32
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpNestedStatementsTest.cs
@@ -0,0 +1,104 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpNestedStatementsTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void NestedSimpleStatement()
+ {
+ ParseBlockTest("@while(true) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void NestedKeywordStatement()
+ {
+ ParseBlockTest("@while(true) { for(int i = 0; i < 10; i++) { foo(); } }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { for(int i = 0; i < 10; i++) { foo(); } }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void NestedCodeBlock()
+ {
+ ParseBlockTest("@while(true) { { { { foo(); } } } }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { { { { foo(); } } } }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void NestedImplicitExpression()
+ {
+ ParseBlockTest("@while(true) { @foo }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { ")
+ .AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Code(" }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void NestedExplicitExpression()
+ {
+ ParseBlockTest("@while(true) { @(foo) }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { ")
+ .AsStatement(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(")
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("foo")
+ .AsExpression(),
+ Factory.MetaCode(")")
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void NestedMarkupBlock()
+ {
+ ParseBlockTest("@while(true) { <p>Hello</p> }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) {")
+ .AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Hello"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("}")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs
new file mode 100644
index 0000000000..eb626f3abe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpRazorCommentsTest.cs
@@ -0,0 +1,390 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpRazorCommentsTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void UnterminatedRazorComment()
+ {
+ ParseDocumentTest("@*",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(
+ SpanKindInternal.Comment,
+ new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any))),
+ RazorDiagnosticFactory.CreateParsing_RazorCommentNotTerminated(
+ new SourceSpan(SourceLocation.Zero, contentLength: 2)));
+ }
+
+ [Fact]
+ public void EmptyRazorComment()
+ {
+ ParseDocumentTest("@**@",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void RazorCommentInImplicitExpressionMethodCall()
+ {
+ ParseDocumentTest("@foo(" + Environment.NewLine
+ + "@**@" + Environment.NewLine,
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo(" + Environment.NewLine)
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ new CommentBlock(
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new CSharpSymbol(
+ string.Empty,
+ CSharpSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(Environment.NewLine)
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords))),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void UnterminatedRazorCommentInImplicitExpressionMethodCall()
+ {
+ ParseDocumentTest("@foo(@*",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo(")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ new CommentBlock(
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new CSharpSymbol(
+ string.Empty,
+ CSharpSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any)))),
+ RazorDiagnosticFactory.CreateParsing_RazorCommentNotTerminated(
+ new SourceSpan(new SourceLocation(5, 0, 5), contentLength: 2)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "(", ")"));
+ }
+
+ [Fact]
+ public void RazorCommentInVerbatimBlock()
+ {
+ ParseDocumentTest("@{" + Environment.NewLine
+ + " <text" + Environment.NewLine
+ + " @**@" + Environment.NewLine
+ + "}",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"{Environment.NewLine} ")
+ .AsStatement()
+ .AutoCompleteWith("}"),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text").Accepts(AcceptedCharactersInternal.Any)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ Factory.Markup("}")))),
+ RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
+ new SourceSpan(new SourceLocation(7 + Environment.NewLine.Length, 1, 5), contentLength: 4)),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(7 + Environment.NewLine.Length, 1, 5), contentLength: 4), "text"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void UnterminatedRazorCommentInVerbatimBlock()
+ {
+ ParseDocumentTest("@{@*",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith("}"),
+ new CommentBlock(
+ Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new CSharpSymbol(string.Empty, CSharpSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any)))),
+ RazorDiagnosticFactory.CreateParsing_RazorCommentNotTerminated(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 2)),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void RazorCommentInMarkup()
+ {
+ ParseDocumentTest(
+ "<p>" + Environment.NewLine
+ + "@**@" + Environment.NewLine
+ + "</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup(Environment.NewLine),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))
+ ));
+ }
+
+ [Fact]
+ public void MultipleRazorCommentInMarkup()
+ {
+ ParseDocumentTest(
+ "<p>" + Environment.NewLine
+ + " @**@ " + Environment.NewLine
+ + "@**@" + Environment.NewLine
+ + "</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup(Environment.NewLine),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" " + Environment.NewLine).With(SpanChunkGenerator.Null),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))
+ ));
+ }
+
+ [Fact]
+ public void MultipleRazorCommentsInSameLineInMarkup()
+ {
+ ParseDocumentTest(
+ "<p>" + Environment.NewLine
+ + "@**@ @**@" + Environment.NewLine
+ + "</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup(Environment.NewLine),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml(),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ string.Empty,
+ HtmlSymbolType.Unknown))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))
+ ));
+ }
+
+ [Fact]
+ public void RazorCommentsSurroundingMarkup()
+ {
+ ParseDocumentTest(
+ "<p>" + Environment.NewLine
+ + "@* hello *@ content @* world *@" + Environment.NewLine
+ + "</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup(Environment.NewLine),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ " hello ",
+ HtmlSymbolType.RazorComment))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" content "),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ " world ",
+ HtmlSymbolType.RazorComment))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))
+ ));
+ }
+
+ [Fact]
+ public void RazorCommentWithExtraNewLineInMarkup()
+ {
+ ParseDocumentTest(
+ "<p>" + Environment.NewLine + Environment.NewLine
+ + "@* content *@" + Environment.NewLine
+ + "@*" + Environment.NewLine
+ + "content" + Environment.NewLine
+ + "*@" + Environment.NewLine + Environment.NewLine
+ + "</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup(Environment.NewLine + Environment.NewLine),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ " content ",
+ HtmlSymbolType.RazorComment))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(
+ Environment.NewLine + "content" + Environment.NewLine,
+ HtmlSymbolType.RazorComment))
+ .Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).With(SpanChunkGenerator.Null),
+ Factory.Markup(Environment.NewLine),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpReservedWordsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpReservedWordsTest.cs
new file mode 100644
index 0000000000..21a2dacf19
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpReservedWordsTest.cs
@@ -0,0 +1,40 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpReservedWordsTest : CsHtmlCodeParserTestBase
+ {
+ [Theory]
+ [InlineData("namespace")]
+ [InlineData("class")]
+ public void ReservedWords(string word)
+ {
+ ParseBlockTest(word,
+ new DirectiveBlock(
+ Factory.MetaCode(word).Accepts(AcceptedCharactersInternal.None)
+ ),
+ RazorDiagnosticFactory.CreateParsing_ReservedWord(
+ new SourceSpan(SourceLocation.Zero, word.Length), word));
+ }
+
+ [Theory]
+ [InlineData("Namespace")]
+ [InlineData("Class")]
+ [InlineData("NAMESPACE")]
+ [InlineData("CLASS")]
+ [InlineData("nameSpace")]
+ [InlineData("NameSpace")]
+ private void ReservedWordsAreCaseSensitive(string word)
+ {
+ ParseBlockTest(word,
+ new ExpressionBlock(
+ Factory.Code(word)
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs
new file mode 100644
index 0000000000..3e2fbac20f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs
@@ -0,0 +1,766 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpSectionTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void ParseSectionBlockCapturesNewlineImmediatelyFollowing()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: Environment.NewLine.Length), SectionDirective.Directive.Directive));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section" + Environment.NewLine,
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, string.Empty, CSharpSymbolType.Unknown)
+ .AsDirectiveToken(DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Member))),
+ Factory.Markup(Environment.NewLine)));
+ }
+
+ [Fact]
+ public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingOpenBrace()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
+ new SourceSpan(new SourceLocation(25 + Environment.NewLine.Length, 1, 4), contentLength: 1),
+ SectionDirective.Directive.Directive,
+ "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section Foo " + Environment.NewLine + " ",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " " + Environment.NewLine + " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingName()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: Environment.NewLine.Length), SectionDirective.Directive.Directive));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section " + Environment.NewLine + " ",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory
+ .Span(SpanKindInternal.Code, string.Empty, CSharpSymbolType.Unknown)
+ .AsDirectiveToken(DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Member))),
+ Factory.Markup(Environment.NewLine + " ")));
+ }
+
+ [Fact]
+ public void ParseSectionBlockIgnoresSectionUnlessAllLowerCase()
+ {
+ ParseDocumentTest(
+ "@Section foo",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("Section")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" foo")));
+ }
+
+ [Fact]
+ public void ParseSectionBlockReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartCharacter()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsIdentifier(
+ new SourceSpan(new SourceLocation(9, 0, 9), contentLength: 1), SectionDirective.Directive.Directive));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section 9 { <p>Foo</p> }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace)),
+ Factory.Markup("9 { "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" }")));
+ }
+
+ [Fact]
+ public void ParseSectionBlockReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedDirectiveLiteral(
+ new SourceSpan(new SourceLocation(12, 0, 12), contentLength: 1),
+ SectionDirective.Directive.Directive,
+ "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo-bar { <p>Foo</p> }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0])),
+ Factory.Markup("-bar { "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" }")));
+ }
+
+ [Fact]
+ public void ParserOutputsErrorOnNestedSections()
+ {
+ // Arrange
+ var erroredChunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ erroredChunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveMustAppearAtStartOfLine(
+ new SourceSpan(new SourceLocation(16, 0, 16), contentLength: 7), "section"));
+ erroredChunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_SectionsCannotBeNested(
+ new SourceSpan(new SourceLocation(15, 0, 15), 8)));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo { @section bar { <p>Foo</p> } }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new DirectiveBlock(erroredChunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "bar", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockHandlesEOFAfterOpenBrace()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(13, 0, 13), contentLength: 1), SectionDirective.Directive.Directive, "}", "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo {",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.EmptyHtml()))));
+ }
+
+ [Theory]
+ [InlineData(" ")]
+ [InlineData("\n")]
+ [InlineData(" abc")]
+ [InlineData(" \n abc")]
+ public void ParseSectionBlockHandlesEOFAfterOpenContent(string postStartBrace)
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(13, 0, 13), contentLength: 1), "section", "}", "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo {" + postStartBrace,
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(postStartBrace)))));
+ }
+
+ [Fact]
+ public void ParseSectionBlockHandlesUnterminatedSection()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(13, 0, 13), contentLength: 1), "section", "}", "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo { <p>Foo{}</p>",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ // Need to provide the markup span as fragments, since the parser will split the {} into separate symbols.
+ Factory.Markup("Foo", "{", "}"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>"))))));
+ }
+
+ [Fact]
+ public void ParseSectionBlockHandlesUnterminatedSectionWithNestedIf()
+ {
+ // Arrange
+ var newLine = Environment.NewLine;
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(13 + newLine.Length, 1, 0), contentLength: 1), "section", "}", "{"));
+ var spaces = " ";
+
+ // Act & Assert
+ ParseDocumentTest(
+ string.Format(
+ "@section Test{0}{{{0}{1}@if(true){0}{1}{{{0}{1}{1}<p>Hello World</p>{0}{1}}}",
+ newLine,
+ spaces),
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Test", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, Environment.NewLine, CSharpSymbolType.NewLine).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(newLine),
+ new StatementBlock(
+ Factory.Code(spaces).AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code($"if(true){newLine}{spaces}{{{newLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup($"{spaces}{spaces}"),
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Hello World"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(newLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code($"{spaces}}}").AsStatement())))));
+ }
+
+ [Fact]
+ public void ParseSectionBlockReportsErrorAndAcceptsWhitespaceToEndOfLineIfSectionNotFollowedByOpenBrace()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(SectionDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
+ new SourceSpan(new SourceLocation(18 + Environment.NewLine.Length, 1, 0), contentLength: 1),
+ SectionDirective.Directive.Directive,
+ "{"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo " + Environment.NewLine,
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " " + Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockAcceptsOpenBraceMultipleLinesBelowSectionName()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo "
+ + Environment.NewLine
+ + Environment.NewLine
+ + Environment.NewLine
+ + Environment.NewLine
+ + Environment.NewLine
+ + Environment.NewLine
+ + "{" + Environment.NewLine
+ + "<p>Foo</p>" + Environment.NewLine
+ + "}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " " + string.Format("{0}{0}{0}{0}{0}{0}", Environment.NewLine), markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(Environment.NewLine)),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockParsesNamedSectionCorrectly()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo { <p>Foo</p> }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockDoesNotRequireSpaceBetweenSectionNameAndOpenBrace()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo{ <p>Foo</p> }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>")),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockBalancesBraces()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo { <script>(function foo() { return 1; })();</script> }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<script>")),
+ Factory.Markup("(function foo() { return 1; })();"),
+ new MarkupTagBlock(
+ Factory.Markup("</script>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockAllowsBracesInCSharpExpression()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo { I really want to render a close brace, so here I go: @(\"}\") }",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" I really want to render a close brace, so here I go: "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\"}\"").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void SectionIsCorrectlyTerminatedWhenCloseBraceImmediatelyFollowsCodeBlock()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section Foo {" + Environment.NewLine
+ + "@if(true) {" + Environment.NewLine
+ + "}" + Environment.NewLine
+ + "}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code($"if(true) {{{Environment.NewLine}}}{Environment.NewLine}").AsStatement()
+ )),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void SectionIsCorrectlyTerminatedWhenCloseBraceImmediatelyFollowsCodeBlockNoWhitespace()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section Foo {" + Environment.NewLine
+ + "@if(true) {" + Environment.NewLine
+ + "}}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code($"if(true) {{{Environment.NewLine}}}").AsStatement()
+ )),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockCorrectlyTerminatesWhenCloseBraceImmediatelyFollowsMarkup()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section foo {something}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup("something")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockParsesComment()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section s {<!-- -->}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ BlockFactory.HtmlCommentBlock(" "),
+ Factory.EmptyHtml()),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ // This was a user reported bug (codeplex #710), the section parser wasn't handling
+ // comments.
+ [Fact]
+ public void ParseSectionBlockParsesCommentWithDelimiters()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section s {<!-- > \" '-->}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ BlockFactory.HtmlCommentBlock(" > \" '"),
+ Factory.EmptyHtml()),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockCommentRecoversFromUnclosedTag()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section s {" + Environment.NewLine + "<a" + Environment.NewLine + "<!-- > \" '-->}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine),
+ new MarkupTagBlock(
+ Factory.Markup("<a" + Environment.NewLine)),
+ BlockFactory.HtmlCommentBlock(" > \" '"),
+ Factory.EmptyHtml()),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseSectionBlockParsesXmlProcessingInstruction()
+ {
+ // Act & Assert
+ ParseDocumentTest(
+ "@section s { <? xml bleh ?>}",
+ new[] { SectionDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" <? xml bleh ?>")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ public static TheoryData SectionWithEscapedTransitionData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ return new TheoryData<string, Block>
+ {
+ {
+ "@section s {<span foo='@@' />}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ factory.CodeTransition(),
+ factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 17, 0, 17), new LocationTagged<string>("'", 25, 0, 25)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 23, 0, 23), new LocationTagged<string>("@", 23, 0, 23))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />"))),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml())
+ },
+ {
+ "@section s {<span foo='@DateTime.Now @@' />}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ factory.CodeTransition(),
+ factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 17, 0, 17), new LocationTagged<string>("'", 39, 0, 39)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 23, 0, 23), 23, 0, 23),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 36, 0, 36), new LocationTagged<string>("@", 37, 0, 37))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />"))),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml())
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(SectionWithEscapedTransitionData))]
+ public void ParseSectionBlock_WithDoubleTransition_DoesNotThrow(string input, object expected)
+ {
+ FixupSpans = true;
+
+ ParseDocumentTest(input, new[] { SectionDirective.Directive }, (Block)expected);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs
new file mode 100644
index 0000000000..ca472f33f5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs
@@ -0,0 +1,246 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpSpecialBlockTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void ParseInheritsStatementMarksInheritsSpanAsCanGrowIfMissingTrailingSpace()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(InheritsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEOFAfterDirective(
+ new SourceSpan(new SourceLocation(9, 0, 9), 1), InheritsDirective.Directive.Directive, "type"));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@inherits",
+ new[] { InheritsDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, string.Empty, CSharpSymbolType.Unknown)
+ .AsDirectiveToken(DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Type))),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void InheritsBlockAcceptsMultipleGenericArguments()
+ {
+ ParseDocumentTest(
+ "@inherits Foo.Bar<Biz<Qux>, string, int>.Baz",
+ new[] { InheritsDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(InheritsDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo.Bar<Biz<Qux>, string, int>.Baz", markup: false).AsDirectiveToken(InheritsDirective.Directive.Tokens[0])),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void InheritsBlockOutputsErrorIfInheritsNotFollowedByTypeButAcceptsEntireLineAsCode()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(InheritsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_DirectiveExpectsTypeName(
+ new SourceSpan(new SourceLocation(25, 0, 25), Environment.NewLine.Length),
+ InheritsDirective.Directive.Directive));
+
+ // Act & Assert
+ ParseDocumentTest(
+ "@inherits " + Environment.NewLine + "foo",
+ new[] { InheritsDirective.Directive },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(chunkGenerator,
+ Factory.CodeTransition(),
+ Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, string.Empty, CSharpSymbolType.Unknown)
+ .AsDirectiveToken(DirectiveTokenDescriptor.CreateToken(DirectiveTokenKind.Type))),
+ Factory.Markup(Environment.NewLine + "foo")));
+ }
+
+ [Fact]
+ public void NamespaceImportInsideCodeBlockCausesError()
+ {
+ ParseBlockTest("{ using Foo.Bar.Baz; var foo = bar; }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" using Foo.Bar.Baz; var foo = bar; ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ),
+ RazorDiagnosticFactory.CreateParsing_NamespaceImportAndTypeAliasCannotExistWithinCodeBlock(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 5)));
+ }
+
+ [Fact]
+ public void TypeAliasInsideCodeBlockIsNotHandledSpecially()
+ {
+ ParseBlockTest("{ using Foo = Bar.Baz; var foo = bar; }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" using Foo = Bar.Baz; var foo = bar; ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ),
+ RazorDiagnosticFactory.CreateParsing_NamespaceImportAndTypeAliasCannotExistWithinCodeBlock(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 5)));
+ }
+
+ [Fact]
+ public void Plan9FunctionsKeywordInsideCodeBlockIsNotHandledSpecially()
+ {
+ ParseBlockTest("{ functions Foo; }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" functions Foo; ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void NonKeywordStatementInCodeBlockIsHandledCorrectly()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " List<dynamic> photos = gallery.Photo.ToList();" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"{Environment.NewLine} List<dynamic> photos = gallery.Photo.ToList();{Environment.NewLine}")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockBalancesBracesOutsideStringsIfFirstCharacterIsBraceAndReturnsSpanOfTypeCode()
+ {
+ // Arrange
+ const string code = "foo\"b}ar\" if(condition) { string.Format(\"{0}\"); } ";
+
+ // Act/Assert
+ ParseBlockTest("{" + code + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(code)
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockBalancesParensOutsideStringsIfFirstCharacterIsParenAndReturnsSpanOfTypeExpression()
+ {
+ // Arrange
+ const string code = "foo\"b)ar\" if(condition) { string.Format(\"{0}\"); } ";
+
+ // Act/Assert
+ ParseBlockTest("(" + code + ")",
+ new ExpressionBlock(
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(code).AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockBalancesBracesAndOutputsContentAsClassLevelCodeSpanIfFirstIdentifierIsFunctionsKeyword()
+ {
+ const string code = " foo(); \"bar}baz\" ";
+ ParseBlockTest(
+ "functions {" + code + "} zoop",
+ new[] { FunctionsDirective.Directive },
+ new DirectiveBlock(new DirectiveChunkGenerator(FunctionsDirective.Directive),
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(code).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNoErrorRecoveryForFunctionsBlock()
+ {
+ // Arrange
+ var chunkGenerator = new DirectiveChunkGenerator(FunctionsDirective.Directive);
+ chunkGenerator.Diagnostics.Add(
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 1), "functions", "}", "{"));
+
+ // Act & Assert
+ ParseBlockTest(
+ "functions { { { { { } zoop",
+ new[] { FunctionsDirective.Directive },
+ new DirectiveBlock(chunkGenerator,
+ Factory.MetaCode("functions").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" { { { { } zoop").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockIgnoresFunctionsUnlessAllLowerCase()
+ {
+ ParseBlockTest("Functions { foo() }",
+ new ExpressionBlock(
+ Factory.Code("Functions")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)));
+ }
+
+ [Fact]
+ public void ParseBlockIgnoresSingleSlashAtStart()
+ {
+ ParseBlockTest("@/ foo",
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1),
+ "/"));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesSingleLineCommentAtEndOfLine()
+ {
+ ParseBlockTest("if(!false) {" + Environment.NewLine
+ + " // Foo" + Environment.NewLine
+ + "\t<p>A real tag!</p>" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code($"if(!false) {{{Environment.NewLine} // Foo{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup("\t"),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("A real tag!"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement()
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpStatementTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpStatementTest.cs
new file mode 100644
index 0000000000..0d3a485441
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpStatementTest.cs
@@ -0,0 +1,432 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ // Basic Tests for C# Statements:
+ // * Basic case for each statement
+ // * Basic case for ALL clauses
+
+ // This class DOES NOT contain
+ // * Error cases
+ // * Tests for various types of nested statements
+ // * Comment tests
+
+ public class CSharpStatementTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void ForStatement()
+ {
+ ParseBlockTest("@for(int i = 0; i++; i < length) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("for(int i = 0; i++; i < length) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ForEachStatement()
+ {
+ ParseBlockTest("@foreach(var foo in bar) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foreach(var foo in bar) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void WhileStatement()
+ {
+ ParseBlockTest("@while(true) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("while(true) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void SwitchStatement()
+ {
+ ParseBlockTest("@switch(foo) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("switch(foo) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void LockStatement()
+ {
+ ParseBlockTest("@lock(baz) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("lock(baz) { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void IfStatement()
+ {
+ ParseBlockTest("@if(true) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true) { foo(); }")
+ .AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ElseIfClause()
+ {
+ ParseBlockTest("@if(true) { foo(); } else if(false) { foo(); } else if(!false) { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true) { foo(); } else if(false) { foo(); } else if(!false) { foo(); }")
+ .AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void ElseClause()
+ {
+ ParseBlockTest("@if(true) { foo(); } else { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true) { foo(); } else { foo(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void TryStatement()
+ {
+ ParseBlockTest("@try { foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("try { foo(); }")
+ .AsStatement()
+ ));
+ }
+
+ [Fact]
+ public void CatchClause()
+ {
+ ParseBlockTest("@try { foo(); } catch(IOException ioex) { handleIO(); } catch(Exception ex) { handleOther(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("try { foo(); } catch(IOException ioex) { handleIO(); } catch(Exception ex) { handleOther(); }")
+ .AsStatement()
+ ));
+ }
+
+ public static TheoryData ExceptionFilterData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ // document, expectedStatement
+ return new TheoryData<string, StatementBlock>
+ {
+ {
+ "@try { someMethod(); } catch(Exception) when (true) { handleIO(); }",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (true) { handleIO(); }")
+ .AsStatement())
+ },
+ {
+ "@try { A(); } catch(Exception) when (true) { B(); } finally { C(); }",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { A(); } catch(Exception) when (true) { B(); } finally { C(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None))
+ },
+ {
+ "@try { A(); } catch(Exception) when (true) { B(); } catch(IOException) when (false) { C(); }",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { A(); } catch(Exception) when (true) { B(); } catch(IOException) " +
+ "when (false) { C(); }")
+ .AsStatement())
+ },
+ {
+ string.Format("@try{0}{{{0} A();{0}}}{0}catch(Exception) when (true)", Environment.NewLine) +
+ string.Format("{0}{{{0} B();{0}}}{0}catch(IOException) when (false)", Environment.NewLine) +
+ string.Format("{0}{{{0} C();{0}}}", Environment.NewLine),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code(
+ string.Format("try{0}{{{0} A();{0}}}{0}catch(Exception) ", Environment.NewLine) +
+ string.Format("when (true){0}{{{0} B();{0}}}{0}", Environment.NewLine) +
+ string.Format("catch(IOException) when (false){0}{{{0} ", Environment.NewLine) +
+ string.Format("C();{0}}}", Environment.NewLine))
+ .AsStatement())
+ },
+
+ // Wrapped in @{ block.
+ {
+ "@{try { someMethod(); } catch(Exception) when (true) { handleIO(); }}",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (true) { handleIO(); }")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None))
+ },
+
+ // Partial exception filter data
+ {
+ "@try { someMethod(); } catch(Exception) when",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when")
+ .AsStatement())
+ },
+ {
+ "@try { someMethod(); } when",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); }")
+ .AsStatement())
+ },
+ {
+ "@try { someMethod(); } catch(Exception) when { anotherMethod(); }",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when { anotherMethod(); }")
+ .AsStatement())
+ },
+ {
+ "@try { someMethod(); } catch(Exception) when (true)",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (true)")
+ .AsStatement())
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ExceptionFilterData))]
+ public void ExceptionFilters(string document, object expectedStatement)
+ {
+ FixupSpans = true;
+
+ // Act & Assert
+ ParseBlockTest(document, (StatementBlock)expectedStatement);
+ }
+
+ public static TheoryData ExceptionFilterErrorData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ // document, expectedStatement, expectedErrors
+ return new TheoryData<string, StatementBlock, RazorDiagnostic[]>
+ {
+ {
+ "@try { someMethod(); } catch(Exception) when (",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (")
+ .AsStatement()),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(45, 0, 45), contentLength: 1), "(", ")"),
+ }
+ },
+ {
+ "@try { someMethod(); } catch(Exception) when (someMethod(",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (someMethod(")
+ .AsStatement()),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedCloseBracketBeforeEOF(
+ new SourceSpan(new SourceLocation(45, 0, 45), contentLength: 1), "(", ")"),
+ }
+ },
+ {
+ "@try { someMethod(); } catch(Exception) when (true) {",
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory
+ .Code("try { someMethod(); } catch(Exception) when (true) {")
+ .AsStatement()),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(23, 0, 23), contentLength: 1), "catch", "}", "{"),
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ExceptionFilterErrorData))]
+ public void ExceptionFilterErrors(
+ string document,
+ object expectedStatement,
+ object expectedErrors)
+ {
+ FixupSpans = true;
+
+ // Act & Assert
+ ParseBlockTest(document, (StatementBlock)expectedStatement, (RazorDiagnostic[])expectedErrors);
+ }
+
+ [Fact]
+ public void FinallyClause()
+ {
+ ParseBlockTest("@try { foo(); } finally { Dispose(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("try { foo(); } finally { Dispose(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ public static TheoryData StaticUsingData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ Func<string, string, DirectiveBlock> createUsing = (code, import) =>
+ new DirectiveBlock(
+ factory.CodeTransition(),
+ factory.Code(code)
+ .AsNamespaceImport(import)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline));
+
+ // document, expectedResult
+ return new TheoryData<string, DirectiveBlock>
+ {
+ { "@using static", createUsing("using static", " static") },
+ { "@using static ", createUsing("using static ", " static ") },
+ { "@using static ", createUsing("using static ", " static ") },
+ { "@using static System", createUsing("using static System", " static System") },
+ {
+ "@using static System",
+ createUsing("using static System", " static System")
+ },
+ {
+ "@using static System.Console",
+ createUsing("using static System.Console", " static System.Console")
+ },
+ {
+ "@using static global::System.Console",
+ createUsing("using static global::System.Console", " static global::System.Console")
+ },
+ {
+ "@using static global::System.Console ",
+ createUsing("using static global::System.Console", " static global::System.Console")
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(StaticUsingData))]
+ public void StaticUsingImport(string document, object expectedResult)
+ {
+ FixupSpans = true;
+
+ // Act & Assert
+ ParseBlockTest(document, (DirectiveBlock)expectedResult);
+ }
+
+ [Fact]
+ public void UsingStatement()
+ {
+ ParseBlockTest("@using(var foo = new Foo()) { foo.Bar(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("using(var foo = new Foo()) { foo.Bar(); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void UsingTypeAlias()
+ {
+ ParseBlockTest("@using StringDictionary = System.Collections.Generic.Dictionary<string, string>",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.Code("using StringDictionary = System.Collections.Generic.Dictionary<string, string>")
+ .AsNamespaceImport(" StringDictionary = System.Collections.Generic.Dictionary<string, string>")
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)
+ ));
+ }
+
+ [Fact]
+ public void UsingNamespaceImport()
+ {
+ ParseBlockTest("@using System.Text.Encoding.ASCIIEncoding",
+ new DirectiveBlock(
+ Factory.CodeTransition(),
+ Factory.Code("using System.Text.Encoding.ASCIIEncoding")
+ .AsNamespaceImport(" System.Text.Encoding.ASCIIEncoding")
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)
+ ));
+ }
+
+ [Fact]
+ public void DoStatement()
+ {
+ ParseBlockTest("@do { foo(); } while(true);",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("do { foo(); } while(true);")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void NonBlockKeywordTreatedAsImplicitExpression()
+ {
+ ParseBlockTest("@is foo",
+ new ExpressionBlock(new ExpressionChunkGenerator(),
+ Factory.CodeTransition(),
+ Factory.Code("is")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTemplateTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTemplateTest.cs
new file mode 100644
index 0000000000..0631ff1c7f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTemplateTest.cs
@@ -0,0 +1,321 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTemplateTest : CsHtmlCodeParserTestBase
+ {
+ private const string TestTemplateCode = " @<p>Foo #@item</p>";
+
+ private TemplateBlock TestTemplate()
+ {
+ return new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo #"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("item")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ )
+ );
+ }
+
+ private const string TestNestedTemplateCode = " @<p>Foo #@Html.Repeat(10, @<p>@item</p>)</p>";
+
+ private TemplateBlock TestNestedTemplate()
+ {
+ return new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo #"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("Html.Repeat(10, ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("item")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ )
+ ),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ )
+ );
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSingleLineTemplate()
+ {
+ ParseBlockTest("{ var foo = @: bar" + Environment.NewLine
+ + "; }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(" bar" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
+ .Accepts(AcceptedCharactersInternal.None)
+ )
+ ),
+ Factory.Code("; ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSingleLineImmediatelyFollowingStatementChar()
+ {
+ ParseBlockTest("{i@: bar" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("i")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(" bar" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
+ .Accepts(AcceptedCharactersInternal.None)
+ )
+ ),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSimpleTemplateInExplicitExpressionParens()
+ {
+ ParseBlockTest("(Html.Repeat(10," + TestTemplateCode + "))",
+ new ExpressionBlock(
+ Factory.MetaCode("(").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("Html.Repeat(10, ").AsExpression(),
+ TestTemplate(),
+ Factory.Code(")").AsExpression(),
+ Factory.MetaCode(")").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSimpleTemplateInImplicitExpressionParens()
+ {
+ ParseBlockTest("Html.Repeat(10," + TestTemplateCode + ")",
+ new ExpressionBlock(
+ Factory.Code("Html.Repeat(10, ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ TestTemplate(),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesTwoTemplatesInImplicitExpressionParens()
+ {
+ ParseBlockTest("Html.Repeat(10," + TestTemplateCode + "," + TestTemplateCode + ")",
+ new ExpressionBlock(
+ Factory.Code("Html.Repeat(10, ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ TestTemplate(),
+ Factory.Code(", ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ TestTemplate(),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInImplicitExpressionParens()
+ {
+ ParseBlockTest("Html.Repeat(10," + TestNestedTemplateCode + ")",
+ new ExpressionBlock(
+ Factory.Code("Html.Repeat(10, ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ TestNestedTemplate(),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ GetNestedTemplateError(42));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSimpleTemplateInStatementWithinCodeBlock()
+ {
+ ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestTemplateCode + "); }",
+ new StatementBlock(
+ Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ").AsStatement(),
+ TestTemplate(),
+ Factory.Code("); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesTwoTemplatesInStatementWithinCodeBlock()
+ {
+ ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + "); }",
+ new StatementBlock(
+ Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ").AsStatement(),
+ TestTemplate(),
+ Factory.Code(", ").AsStatement(),
+ TestTemplate(),
+ Factory.Code("); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInStatementWithinCodeBlock()
+ {
+ ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestNestedTemplateCode + "); }",
+ new StatementBlock(
+ Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ")
+ .AsStatement(),
+ TestNestedTemplate(),
+ Factory.Code("); }")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)
+ ),
+ GetNestedTemplateError(74));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesSimpleTemplateInStatementWithinStatementBlock()
+ {
+ ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestTemplateCode + "); }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ TestTemplate(),
+ Factory.Code("); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockHandlessTwoTemplatesInStatementWithinStatementBlock()
+ {
+ ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + "); }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ TestTemplate(),
+ Factory.Code(", ").AsStatement(),
+ TestTemplate(),
+ Factory.Code("); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInStatementWithinStatementBlock()
+ {
+ ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestNestedTemplateCode + "); }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ TestNestedTemplate(),
+ Factory.Code("); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ),
+ GetNestedTemplateError(69));
+ }
+
+ [Fact]
+ public void ParseBlock_WithDoubleTransition_DoesNotThrow()
+ {
+ FixupSpans = true;
+
+ // Arrange
+ var testTemplateWithDoubleTransitionCode = " @<p foo='@@'>Foo #@item</p>";
+ var testTemplateWithDoubleTransition = new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 46, 0, 46), new LocationTagged<string>("'", 54, 0, 54)),
+ Factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ Factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 52, 0, 52), new LocationTagged<string>("@", 52, 0, 52))).Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo #"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("item")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ )
+ );
+
+ var expected = new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ testTemplateWithDoubleTransition,
+ Factory.Code("); ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None));
+
+ // Act & Assert
+ ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + testTemplateWithDoubleTransitionCode + "); }", expected);
+ }
+
+ private static RazorDiagnostic GetNestedTemplateError(int characterIndex)
+ {
+ return RazorDiagnosticFactory.CreateParsing_InlineMarkupBlocksCannotBeNested(
+ new SourceSpan(new SourceLocation(characterIndex, 0, characterIndex), contentLength: 1));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpToMarkupSwitchTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpToMarkupSwitchTest.cs
new file mode 100644
index 0000000000..1d96a65590
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpToMarkupSwitchTest.cs
@@ -0,0 +1,691 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpToMarkupSwitchTest : CsHtmlCodeParserTestBase
+ {
+ [Fact]
+ public void SingleAngleBracketDoesNotCauseSwitchIfOuterBlockIsTerminated()
+ {
+ ParseBlockTest("{ List< }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" List< ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockGivesSpacesToCodeOnAtTagTemplateTransitionInDesignTimeMode()
+ {
+ ParseBlockTest("Foo( @<p>Foo</p> )",
+ new ExpressionBlock(
+ Factory.Code("Foo( ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.Any),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ )
+ ),
+ Factory.Code(" )")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ), designTime: true);
+ }
+
+ [Fact]
+ public void ParseBlockGivesSpacesToCodeOnAtColonTemplateTransitionInDesignTimeMode()
+ {
+ ParseBlockTest("Foo( " + Environment.NewLine
+ + "@:<p>Foo</p> " + Environment.NewLine
+ + ")",
+ new ExpressionBlock(
+ Factory.Code("Foo( " + Environment.NewLine).AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("<p>Foo</p> " + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ )
+ ),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ), designTime: true);
+ }
+
+ [Fact]
+ public void ParseBlockGivesSpacesToCodeOnTagTransitionInDesignTimeMode()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " <p>Foo</p> " + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ ),
+ Factory.Code(" " + Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ), designTime: true);
+ }
+
+ [Fact]
+ public void ParseBlockGivesSpacesToCodeOnInvalidAtTagTransitionInDesignTimeMode()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " @<p>Foo</p> " + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))
+ ),
+ Factory.Code(" " + Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ), true,
+ RazorDiagnosticFactory.CreateParsing_AtInCodeMustBeFollowedByColonParenOrIdentifierStart(
+ new SourceSpan(new SourceLocation(5 + Environment.NewLine.Length, 1, 4), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseBlockGivesSpacesToCodeOnAtColonTransitionInDesignTimeMode()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " @:<p>Foo</p> " + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("<p>Foo</p> " + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ), designTime: true);
+ }
+
+ [Fact]
+ public void ParseBlockShouldSupportSingleLineMarkupContainingStatementBlock()
+ {
+ ParseBlockTest("Repeat(10," + Environment.NewLine
+ + " @: @{}" + Environment.NewLine
+ + ")",
+ new ExpressionBlock(
+ Factory.Code($"Repeat(10,{Environment.NewLine} ")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
+ new TemplateBlock(
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(" ")
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Markup(Environment.NewLine)
+ .Accepts(AcceptedCharactersInternal.None)
+ )
+ ),
+ Factory.Code(")")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockShouldSupportMarkupWithoutPreceedingWhitespace()
+ {
+ ParseBlockTest("foreach(var file in files){" + Environment.NewLine
+ + Environment.NewLine
+ + Environment.NewLine
+ + "@:Baz" + Environment.NewLine
+ + "<br/>" + Environment.NewLine
+ + "<a>Foo</a>" + Environment.NewLine
+ + "@:Bar" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code(string.Format("foreach(var file in files){{{0}{0}{0}", Environment.NewLine)).AsStatement(),
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Baz" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<br/>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</a>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Bar" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code("}").AsStatement().Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockGivesAllWhitespaceOnSameLineExcludingPreceedingNewlineButIncludingTrailingNewLineToMarkup()
+ {
+ ParseBlockTest("if(foo) {" + Environment.NewLine
+ + " var foo = \"After this statement there are 10 spaces\"; " + Environment.NewLine
+ + " <p>" + Environment.NewLine
+ + " Foo" + Environment.NewLine
+ + " @bar" + Environment.NewLine
+ + " </p>" + Environment.NewLine
+ + " @:Hello!" + Environment.NewLine
+ + " var biz = boz;" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code(
+ $"if(foo) {{{Environment.NewLine} var foo = \"After this statement there are " +
+ "10 spaces\"; " + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup($"{Environment.NewLine} Foo{Environment.NewLine}"),
+ new ExpressionBlock(
+ Factory.Code(" ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code("bar").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.Markup(Environment.NewLine + " "),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Hello!" + Environment.NewLine).With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code($" var biz = boz;{Environment.NewLine}}}").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsMarkupInIfBodyWithBraces()
+ {
+ ParseBlockTest("if(foo) { <p>Bar</p> } else if(bar) { <p>Baz</p> } else { <p>Boz</p> }",
+ new StatementBlock(
+ Factory.Code("if(foo) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} else if(bar) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} else {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Boz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("}").AsStatement().Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsMarkupInIfBodyWithBracesWithinCodeBlock()
+ {
+ ParseBlockTest("{ if(foo) { <p>Bar</p> } else if(bar) { <p>Baz</p> } else { <p>Boz</p> } }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" if(foo) {")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} else if(bar) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} else {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Boz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupInCaseAndDefaultBranchesOfSwitch()
+ {
+ // Arrange
+ ParseBlockTest("switch(foo) {" + Environment.NewLine
+ + " case 0:" + Environment.NewLine
+ + " <p>Foo</p>" + Environment.NewLine
+ + " break;" + Environment.NewLine
+ + " case 1:" + Environment.NewLine
+ + " <p>Bar</p>" + Environment.NewLine
+ + " return;" + Environment.NewLine
+ + " case 2:" + Environment.NewLine
+ + " {" + Environment.NewLine
+ + " <p>Baz</p>" + Environment.NewLine
+ + " <p>Boz</p>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " default:" + Environment.NewLine
+ + " <p>Biz</p>" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code($"switch(foo) {{{Environment.NewLine} case 0:{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code($" break;{Environment.NewLine} case 1:{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code(
+ $" return;{Environment.NewLine} case 2:{Environment.NewLine}" +
+ " {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Boz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code($" }}{Environment.NewLine} default:{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Biz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("}").AsStatement().Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsMarkupInCaseAndDefaultBranchesOfSwitchInCodeBlock()
+ {
+ // Arrange
+ ParseBlockTest("{ switch(foo) {" + Environment.NewLine
+ + " case 0:" + Environment.NewLine
+ + " <p>Foo</p>" + Environment.NewLine
+ + " break;" + Environment.NewLine
+ + " case 1:" + Environment.NewLine
+ + " <p>Bar</p>" + Environment.NewLine
+ + " return;" + Environment.NewLine
+ + " case 2:" + Environment.NewLine
+ + " {" + Environment.NewLine
+ + " <p>Baz</p>" + Environment.NewLine
+ + " <p>Boz</p>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " default:" + Environment.NewLine
+ + " <p>Biz</p>" + Environment.NewLine
+ + "} }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($" switch(foo) {{{Environment.NewLine} case 0:{Environment.NewLine}")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code($" break;{Environment.NewLine} case 1:{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code(
+ $" return;{Environment.NewLine} case 2:{Environment.NewLine}" +
+ " {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Boz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code($" }}{Environment.NewLine} default:{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Biz"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnOpenAngleBracket()
+ {
+ ParseBlockTest("for(int i = 0; i < 10; i++) { <p>Foo</p> }",
+ new StatementBlock(
+ Factory.Code("for(int i = 0; i < 10; i++) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("}").AsStatement().Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnOpenAngleBracketInCodeBlock()
+ {
+ ParseBlockTest("{ for(int i = 0; i < 10; i++) { <p>Foo</p> } }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" for(int i = 0; i < 10; i++) {")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code("} ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByColon()
+ {
+ // Arrange
+ ParseBlockTest("if(foo) { @:Bar" + Environment.NewLine
+ + "} zoop",
+ new StatementBlock(
+ Factory.Code("if(foo) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Bar" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code("}").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByDoubleColon()
+ {
+ // Arrange
+ ParseBlockTest("if(foo) { @::Sometext" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code("if(foo) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(":Sometext" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code("}").AsStatement()));
+ }
+
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByTripleColon()
+ {
+ // Arrange
+ ParseBlockTest("if(foo) { @:::Sometext" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.Code("if(foo) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("::Sometext" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code("}").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByColonInCodeBlock()
+ {
+ // Arrange
+ ParseBlockTest("{ if(foo) { @:Bar" + Environment.NewLine
+ + "} } zoop",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" if(foo) {")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Bar" + Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code("} ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyReturnsFromMarkupBlockWithPseudoTag()
+ {
+ ParseBlockTest("if (i > 0) { <text>;</text> }",
+ new StatementBlock(
+ Factory.Code("if (i > 0) { ").AsStatement(),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(";").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.Code(" }").AsStatement()));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyReturnsFromMarkupBlockWithPseudoTagInCodeBlock()
+ {
+ ParseBlockTest("{ if (i > 0) { <text>;</text> } }",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" if (i > 0) { ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(";").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.Code(" } ").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsAllKindsOfImplicitMarkupInCodeBlock()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " if(true) {" + Environment.NewLine
+ + " @:Single Line Markup" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " foreach (var p in Enumerable.Range(1, 10)) {" + Environment.NewLine
+ + " <text>The number is @p</text>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " if(!false) {" + Environment.NewLine
+ + " <p>A real tag!</p>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code($"{Environment.NewLine} if(true) {{{Environment.NewLine}")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("Single Line Markup" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ),
+ Factory.Code($" }}{Environment.NewLine} foreach (var p in Enumerable.Range(1, 10)) {{{Environment.NewLine} ").AsStatement(),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("The number is ").Accepts(AcceptedCharactersInternal.None),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.Code($"{Environment.NewLine} }}{Environment.NewLine} if(!false) {{{Environment.NewLine}").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("A real tag!"),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)
+ ),
+ Factory.Code(" }" + Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerCommentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerCommentTest.cs
new file mode 100644
index 0000000000..2ff59a679b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerCommentTest.cs
@@ -0,0 +1,94 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTokenizerCommentTest : CSharpTokenizerTestBase
+ {
+ private new CSharpSymbol IgnoreRemaining => (CSharpSymbol)base.IgnoreRemaining;
+
+ [Fact]
+ public void Next_Ignores_Star_At_EOF_In_RazorComment()
+ {
+ TestTokenizer(
+ "@* Foo * Bar * Baz *",
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol(" Foo * Bar * Baz *", CSharpSymbolType.RazorComment));
+ }
+
+ [Fact]
+ public void Next_Ignores_Star_Without_Trailing_At()
+ {
+ TestTokenizer(
+ "@* Foo * Bar * Baz *@",
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol(" Foo * Bar * Baz ", CSharpSymbolType.RazorComment),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition));
+ }
+
+ [Fact]
+ public void Next_Returns_RazorComment_Token_For_Entire_Razor_Comment()
+ {
+ TestTokenizer(
+ "@* Foo Bar Baz *@",
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol(" Foo Bar Baz ", CSharpSymbolType.RazorComment),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition));
+ }
+
+ [Fact]
+ public void Next_Returns_Comment_Token_For_Entire_Single_Line_Comment()
+ {
+ TestTokenizer("// Foo Bar Baz", new CSharpSymbol("// Foo Bar Baz", CSharpSymbolType.Comment));
+ }
+
+ [Fact]
+ public void Single_Line_Comment_Is_Terminated_By_Newline()
+ {
+ TestTokenizer("// Foo Bar Baz\na", new CSharpSymbol("// Foo Bar Baz", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Multi_Line_Comment_In_Single_Line_Comment_Has_No_Effect()
+ {
+ TestTokenizer("// Foo/*Bar*/ Baz\na", new CSharpSymbol("// Foo/*Bar*/ Baz", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Comment_Token_For_Entire_Multi_Line_Comment()
+ {
+ TestTokenizer("/* Foo\nBar\nBaz */", new CSharpSymbol("/* Foo\nBar\nBaz */", CSharpSymbolType.Comment));
+ }
+
+ [Fact]
+ public void Multi_Line_Comment_Is_Terminated_By_End_Sequence()
+ {
+ TestTokenizer("/* Foo\nBar\nBaz */a", new CSharpSymbol("/* Foo\nBar\nBaz */", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Unterminated_Multi_Line_Comment_Captures_To_EOF()
+ {
+ TestTokenizer("/* Foo\nBar\nBaz", new CSharpSymbol("/* Foo\nBar\nBaz", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Nested_Multi_Line_Comments_Terminated_At_First_End_Sequence()
+ {
+ TestTokenizer("/* Foo/*\nBar\nBaz*/ */", new CSharpSymbol("/* Foo/*\nBar\nBaz*/", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Nested_Multi_Line_Comments_Terminated_At_Full_End_Sequence()
+ {
+ TestTokenizer("/* Foo\nBar\nBaz* */", new CSharpSymbol("/* Foo\nBar\nBaz* */", CSharpSymbolType.Comment), IgnoreRemaining);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerIdentifierTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerIdentifierTest.cs
new file mode 100644
index 0000000000..fe17606261
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerIdentifierTest.cs
@@ -0,0 +1,170 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTokenizerIdentifierTest : CSharpTokenizerTestBase
+ {
+ [Fact]
+ public void Simple_Identifier_Is_Recognized()
+ {
+ TestTokenizer("foo", new CSharpSymbol("foo", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Starting_With_Underscore_Is_Recognized()
+ {
+ TestTokenizer("_foo", new CSharpSymbol("_foo", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Digits()
+ {
+ TestTokenizer("foo4", new CSharpSymbol("foo4", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Start_With_Titlecase_Letter()
+ {
+ TestTokenizer("ῼfoo", new CSharpSymbol("ῼfoo", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Start_With_Letter_Modifier()
+ {
+ TestTokenizer("ᵊfoo", new CSharpSymbol("ᵊfoo", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Start_With_Other_Letter()
+ {
+ TestTokenizer("ƻfoo", new CSharpSymbol("ƻfoo", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Start_With_Number_Letter()
+ {
+ TestTokenizer("Ⅽool", new CSharpSymbol("Ⅽool", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Non_Spacing_Mark()
+ {
+ TestTokenizer("foo\u0300", new CSharpSymbol("foo\u0300", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Spacing_Combining_Mark()
+ {
+ TestTokenizer("fooः", new CSharpSymbol("fooः", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Non_English_Digit()
+ {
+ TestTokenizer("foo١", new CSharpSymbol("foo١", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Connector_Punctuation()
+ {
+ TestTokenizer("foo‿bar", new CSharpSymbol("foo‿bar", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Identifier_Can_Contain_Format_Character()
+ {
+ TestTokenizer("foo؃bar", new CSharpSymbol("foo؃bar", CSharpSymbolType.Identifier));
+ }
+
+ [Fact]
+ public void Keywords_Are_Recognized_As_Keyword_Tokens()
+ {
+ TestKeyword("abstract", CSharpKeyword.Abstract);
+ TestKeyword("byte", CSharpKeyword.Byte);
+ TestKeyword("class", CSharpKeyword.Class);
+ TestKeyword("delegate", CSharpKeyword.Delegate);
+ TestKeyword("event", CSharpKeyword.Event);
+ TestKeyword("fixed", CSharpKeyword.Fixed);
+ TestKeyword("if", CSharpKeyword.If);
+ TestKeyword("internal", CSharpKeyword.Internal);
+ TestKeyword("new", CSharpKeyword.New);
+ TestKeyword("override", CSharpKeyword.Override);
+ TestKeyword("readonly", CSharpKeyword.Readonly);
+ TestKeyword("short", CSharpKeyword.Short);
+ TestKeyword("struct", CSharpKeyword.Struct);
+ TestKeyword("try", CSharpKeyword.Try);
+ TestKeyword("unsafe", CSharpKeyword.Unsafe);
+ TestKeyword("volatile", CSharpKeyword.Volatile);
+ TestKeyword("as", CSharpKeyword.As);
+ TestKeyword("do", CSharpKeyword.Do);
+ TestKeyword("is", CSharpKeyword.Is);
+ TestKeyword("params", CSharpKeyword.Params);
+ TestKeyword("ref", CSharpKeyword.Ref);
+ TestKeyword("switch", CSharpKeyword.Switch);
+ TestKeyword("ushort", CSharpKeyword.Ushort);
+ TestKeyword("while", CSharpKeyword.While);
+ TestKeyword("case", CSharpKeyword.Case);
+ TestKeyword("const", CSharpKeyword.Const);
+ TestKeyword("explicit", CSharpKeyword.Explicit);
+ TestKeyword("float", CSharpKeyword.Float);
+ TestKeyword("null", CSharpKeyword.Null);
+ TestKeyword("sizeof", CSharpKeyword.Sizeof);
+ TestKeyword("typeof", CSharpKeyword.Typeof);
+ TestKeyword("implicit", CSharpKeyword.Implicit);
+ TestKeyword("private", CSharpKeyword.Private);
+ TestKeyword("this", CSharpKeyword.This);
+ TestKeyword("using", CSharpKeyword.Using);
+ TestKeyword("extern", CSharpKeyword.Extern);
+ TestKeyword("return", CSharpKeyword.Return);
+ TestKeyword("stackalloc", CSharpKeyword.Stackalloc);
+ TestKeyword("uint", CSharpKeyword.Uint);
+ TestKeyword("base", CSharpKeyword.Base);
+ TestKeyword("catch", CSharpKeyword.Catch);
+ TestKeyword("continue", CSharpKeyword.Continue);
+ TestKeyword("double", CSharpKeyword.Double);
+ TestKeyword("for", CSharpKeyword.For);
+ TestKeyword("in", CSharpKeyword.In);
+ TestKeyword("lock", CSharpKeyword.Lock);
+ TestKeyword("object", CSharpKeyword.Object);
+ TestKeyword("protected", CSharpKeyword.Protected);
+ TestKeyword("static", CSharpKeyword.Static);
+ TestKeyword("false", CSharpKeyword.False);
+ TestKeyword("public", CSharpKeyword.Public);
+ TestKeyword("sbyte", CSharpKeyword.Sbyte);
+ TestKeyword("throw", CSharpKeyword.Throw);
+ TestKeyword("virtual", CSharpKeyword.Virtual);
+ TestKeyword("decimal", CSharpKeyword.Decimal);
+ TestKeyword("else", CSharpKeyword.Else);
+ TestKeyword("operator", CSharpKeyword.Operator);
+ TestKeyword("string", CSharpKeyword.String);
+ TestKeyword("ulong", CSharpKeyword.Ulong);
+ TestKeyword("bool", CSharpKeyword.Bool);
+ TestKeyword("char", CSharpKeyword.Char);
+ TestKeyword("default", CSharpKeyword.Default);
+ TestKeyword("foreach", CSharpKeyword.Foreach);
+ TestKeyword("long", CSharpKeyword.Long);
+ TestKeyword("void", CSharpKeyword.Void);
+ TestKeyword("enum", CSharpKeyword.Enum);
+ TestKeyword("finally", CSharpKeyword.Finally);
+ TestKeyword("int", CSharpKeyword.Int);
+ TestKeyword("out", CSharpKeyword.Out);
+ TestKeyword("sealed", CSharpKeyword.Sealed);
+ TestKeyword("true", CSharpKeyword.True);
+ TestKeyword("goto", CSharpKeyword.Goto);
+ TestKeyword("unchecked", CSharpKeyword.Unchecked);
+ TestKeyword("interface", CSharpKeyword.Interface);
+ TestKeyword("break", CSharpKeyword.Break);
+ TestKeyword("checked", CSharpKeyword.Checked);
+ TestKeyword("namespace", CSharpKeyword.Namespace);
+ TestKeyword("when", CSharpKeyword.When);
+ }
+
+ private void TestKeyword(string keyword, CSharpKeyword keywordType)
+ {
+ TestTokenizer(keyword, new CSharpSymbol(keyword, CSharpSymbolType.Keyword) { Keyword = keywordType });
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerLiteralTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerLiteralTest.cs
new file mode 100644
index 0000000000..0d614bf84a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerLiteralTest.cs
@@ -0,0 +1,287 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTokenizerLiteralTest : CSharpTokenizerTestBase
+ {
+ private new CSharpSymbol IgnoreRemaining => (CSharpSymbol)base.IgnoreRemaining;
+
+ [Fact]
+ public void Simple_Integer_Literal_Is_Recognized()
+ {
+ TestSingleToken("01189998819991197253", CSharpSymbolType.IntegerLiteral);
+ }
+
+ [Fact]
+ public void Integer_Type_Suffix_Is_Recognized()
+ {
+ TestSingleToken("42U", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42u", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("42L", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42l", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("42UL", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42Ul", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("42uL", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42ul", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("42LU", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42Lu", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("42lU", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("42lu", CSharpSymbolType.IntegerLiteral);
+ }
+
+ [Fact]
+ public void Trailing_Letter_Is_Not_Part_Of_Integer_Literal_If_Not_Type_Sufix()
+ {
+ TestTokenizer("42a", new CSharpSymbol("42", CSharpSymbolType.IntegerLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Simple_Hex_Literal_Is_Recognized()
+ {
+ TestSingleToken("0x0123456789ABCDEF", CSharpSymbolType.IntegerLiteral);
+ }
+
+ [Fact]
+ public void Integer_Type_Suffix_Is_Recognized_In_Hex_Literal()
+ {
+ TestSingleToken("0xDEADBEEFU", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFu", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("0xDEADBEEFL", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFl", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("0xDEADBEEFUL", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFUl", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("0xDEADBEEFuL", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFul", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("0xDEADBEEFLU", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFLu", CSharpSymbolType.IntegerLiteral);
+
+ TestSingleToken("0xDEADBEEFlU", CSharpSymbolType.IntegerLiteral);
+ TestSingleToken("0xDEADBEEFlu", CSharpSymbolType.IntegerLiteral);
+ }
+
+ [Fact]
+ public void Trailing_Letter_Is_Not_Part_Of_Hex_Literal_If_Not_Type_Sufix()
+ {
+ TestTokenizer("0xDEADBEEFz", new CSharpSymbol("0xDEADBEEF", CSharpSymbolType.IntegerLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Dot_Followed_By_Non_Digit_Is_Not_Part_Of_Real_Literal()
+ {
+ TestTokenizer("3.a", new CSharpSymbol("3", CSharpSymbolType.IntegerLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Simple_Real_Literal_Is_Recognized()
+ {
+ TestTokenizer("3.14159", new CSharpSymbol("3.14159", CSharpSymbolType.RealLiteral));
+ }
+
+ [Fact]
+ public void Real_Literal_Between_Zero_And_One_Is_Recognized()
+ {
+ TestTokenizer(".14159", new CSharpSymbol(".14159", CSharpSymbolType.RealLiteral));
+ }
+
+ [Fact]
+ public void Integer_With_Real_Type_Suffix_Is_Recognized()
+ {
+ TestSingleToken("42F", CSharpSymbolType.RealLiteral);
+ TestSingleToken("42f", CSharpSymbolType.RealLiteral);
+ TestSingleToken("42D", CSharpSymbolType.RealLiteral);
+ TestSingleToken("42d", CSharpSymbolType.RealLiteral);
+ TestSingleToken("42M", CSharpSymbolType.RealLiteral);
+ TestSingleToken("42m", CSharpSymbolType.RealLiteral);
+ }
+
+ [Fact]
+ public void Integer_With_Exponent_Is_Recognized()
+ {
+ TestSingleToken("1e10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("1E10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("1e+10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("1E+10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("1e-10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("1E-10", CSharpSymbolType.RealLiteral);
+ }
+
+ [Fact]
+ public void Real_Number_With_Type_Suffix_Is_Recognized()
+ {
+ TestSingleToken("3.14F", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14f", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14D", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14d", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14M", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14m", CSharpSymbolType.RealLiteral);
+ }
+
+ [Fact]
+ public void Real_Number_With_Exponent_Is_Recognized()
+ {
+ TestSingleToken("3.14E10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14e10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14E+10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14e+10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14E-10", CSharpSymbolType.RealLiteral);
+ TestSingleToken("3.14e-10", CSharpSymbolType.RealLiteral);
+ }
+
+ [Fact]
+ public void Real_Number_With_Exponent_And_Type_Suffix_Is_Recognized()
+ {
+ TestSingleToken("3.14E+10F", CSharpSymbolType.RealLiteral);
+ }
+
+ [Fact]
+ public void Single_Character_Literal_Is_Recognized()
+ {
+ TestSingleToken("'f'", CSharpSymbolType.CharacterLiteral);
+ }
+
+ [Fact]
+ public void Multi_Character_Literal_Is_Recognized()
+ {
+ TestSingleToken("'foo'", CSharpSymbolType.CharacterLiteral);
+ }
+
+ [Fact]
+ public void Character_Literal_Is_Terminated_By_EOF_If_Unterminated()
+ {
+ TestSingleToken("'foo bar", CSharpSymbolType.CharacterLiteral);
+ }
+
+ [Fact]
+ public void Character_Literal_Not_Terminated_By_Escaped_Quote()
+ {
+ TestSingleToken("'foo\\'bar'", CSharpSymbolType.CharacterLiteral);
+ }
+
+ [Fact]
+ public void Character_Literal_Is_Terminated_By_EOL_If_Unterminated()
+ {
+ TestTokenizer("'foo\n", new CSharpSymbol("'foo", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Character_Literal_Terminated_By_EOL_Even_When_Last_Char_Is_Slash()
+ {
+ TestTokenizer("'foo\\\n", new CSharpSymbol("'foo\\", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Character_Literal_Terminated_By_EOL_Even_When_Last_Char_Is_Slash_And_Followed_By_Stuff()
+ {
+ TestTokenizer("'foo\\\nflarg", new CSharpSymbol("'foo\\", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Character_Literal_Terminated_By_CRLF_Even_When_Last_Char_Is_Slash()
+ {
+ TestTokenizer("'foo\\" + Environment.NewLine, new CSharpSymbol("'foo\\", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Character_Literal_Terminated_By_CRLF_Even_When_Last_Char_Is_Slash_And_Followed_By_Stuff()
+ {
+ TestTokenizer($"'foo\\{Environment.NewLine}flarg", new CSharpSymbol("'foo\\", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Character_Literal_Allows_Escaped_Escape()
+ {
+ TestTokenizer("'foo\\\\'blah", new CSharpSymbol("'foo\\\\'", CSharpSymbolType.CharacterLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Is_Recognized()
+ {
+ TestSingleToken("\"foo\"", CSharpSymbolType.StringLiteral);
+ }
+
+ [Fact]
+ public void String_Literal_Is_Terminated_By_EOF_If_Unterminated()
+ {
+ TestSingleToken("\"foo bar", CSharpSymbolType.StringLiteral);
+ }
+
+ [Fact]
+ public void String_Literal_Not_Terminated_By_Escaped_Quote()
+ {
+ TestSingleToken("\"foo\\\"bar\"", CSharpSymbolType.StringLiteral);
+ }
+
+ [Fact]
+ public void String_Literal_Is_Terminated_By_EOL_If_Unterminated()
+ {
+ TestTokenizer("\"foo\n", new CSharpSymbol("\"foo", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Terminated_By_EOL_Even_When_Last_Char_Is_Slash()
+ {
+ TestTokenizer("\"foo\\\n", new CSharpSymbol("\"foo\\", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Terminated_By_EOL_Even_When_Last_Char_Is_Slash_And_Followed_By_Stuff()
+ {
+ TestTokenizer("\"foo\\\nflarg", new CSharpSymbol("\"foo\\", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Terminated_By_CRLF_Even_When_Last_Char_Is_Slash()
+ {
+ TestTokenizer("\"foo\\" + Environment.NewLine, new CSharpSymbol("\"foo\\", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Terminated_By_CRLF_Even_When_Last_Char_Is_Slash_And_Followed_By_Stuff()
+ {
+ TestTokenizer($"\"foo\\{Environment.NewLine}flarg", new CSharpSymbol("\"foo\\", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void String_Literal_Allows_Escaped_Escape()
+ {
+ TestTokenizer("\"foo\\\\\"blah", new CSharpSymbol("\"foo\\\\\"", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Verbatim_String_Literal_Can_Contain_Newlines()
+ {
+ TestSingleToken("@\"foo\nbar\nbaz\"", CSharpSymbolType.StringLiteral);
+ }
+
+ [Fact]
+ public void Verbatim_String_Literal_Not_Terminated_By_Escaped_Double_Quote()
+ {
+ TestSingleToken("@\"foo\"\"bar\"", CSharpSymbolType.StringLiteral);
+ }
+
+ [Fact]
+ public void Verbatim_String_Literal_Is_Terminated_By_Slash_Double_Quote()
+ {
+ TestTokenizer("@\"foo\\\"bar\"", new CSharpSymbol("@\"foo\\\"", CSharpSymbolType.StringLiteral), IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Verbatim_String_Literal_Is_Terminated_By_EOF()
+ {
+ TestSingleToken("@\"foo", CSharpSymbolType.StringLiteral);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerOperatorsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerOperatorsTest.cs
new file mode 100644
index 0000000000..67000e950b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerOperatorsTest.cs
@@ -0,0 +1,296 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTokenizerOperatorsTest : CSharpTokenizerTestBase
+ {
+ [Fact]
+ public void LeftBrace_Is_Recognized()
+ {
+ TestSingleToken("{", CSharpSymbolType.LeftBrace);
+ }
+
+ [Fact]
+ public void Plus_Is_Recognized()
+ {
+ TestSingleToken("+", CSharpSymbolType.Plus);
+ }
+
+ [Fact]
+ public void Assign_Is_Recognized()
+ {
+ TestSingleToken("=", CSharpSymbolType.Assign);
+ }
+
+ [Fact]
+ public void Arrow_Is_Recognized()
+ {
+ TestSingleToken("->", CSharpSymbolType.Arrow);
+ }
+
+ [Fact]
+ public void AndAssign_Is_Recognized()
+ {
+ TestSingleToken("&=", CSharpSymbolType.AndAssign);
+ }
+
+ [Fact]
+ public void RightBrace_Is_Recognized()
+ {
+ TestSingleToken("}", CSharpSymbolType.RightBrace);
+ }
+
+ [Fact]
+ public void Minus_Is_Recognized()
+ {
+ TestSingleToken("-", CSharpSymbolType.Minus);
+ }
+
+ [Fact]
+ public void LessThan_Is_Recognized()
+ {
+ TestSingleToken("<", CSharpSymbolType.LessThan);
+ }
+
+ [Fact]
+ public void Equals_Is_Recognized()
+ {
+ TestSingleToken("==", CSharpSymbolType.Equals);
+ }
+
+ [Fact]
+ public void OrAssign_Is_Recognized()
+ {
+ TestSingleToken("|=", CSharpSymbolType.OrAssign);
+ }
+
+ [Fact]
+ public void LeftBracket_Is_Recognized()
+ {
+ TestSingleToken("[", CSharpSymbolType.LeftBracket);
+ }
+
+ [Fact]
+ public void Star_Is_Recognized()
+ {
+ TestSingleToken("*", CSharpSymbolType.Star);
+ }
+
+ [Fact]
+ public void GreaterThan_Is_Recognized()
+ {
+ TestSingleToken(">", CSharpSymbolType.GreaterThan);
+ }
+
+ [Fact]
+ public void NotEqual_Is_Recognized()
+ {
+ TestSingleToken("!=", CSharpSymbolType.NotEqual);
+ }
+
+ [Fact]
+ public void XorAssign_Is_Recognized()
+ {
+ TestSingleToken("^=", CSharpSymbolType.XorAssign);
+ }
+
+ [Fact]
+ public void RightBracket_Is_Recognized()
+ {
+ TestSingleToken("]", CSharpSymbolType.RightBracket);
+ }
+
+ [Fact]
+ public void Slash_Is_Recognized()
+ {
+ TestSingleToken("/", CSharpSymbolType.Slash);
+ }
+
+ [Fact]
+ public void QuestionMark_Is_Recognized()
+ {
+ TestSingleToken("?", CSharpSymbolType.QuestionMark);
+ }
+
+ [Fact]
+ public void LessThanEqual_Is_Recognized()
+ {
+ TestSingleToken("<=", CSharpSymbolType.LessThanEqual);
+ }
+
+ [Fact]
+ public void LeftShift_Is_Not_Specially_Recognized()
+ {
+ TestTokenizer("<<",
+ new CSharpSymbol("<", CSharpSymbolType.LessThan),
+ new CSharpSymbol("<", CSharpSymbolType.LessThan));
+ }
+
+ [Fact]
+ public void LeftParen_Is_Recognized()
+ {
+ TestSingleToken("(", CSharpSymbolType.LeftParenthesis);
+ }
+
+ [Fact]
+ public void Modulo_Is_Recognized()
+ {
+ TestSingleToken("%", CSharpSymbolType.Modulo);
+ }
+
+ [Fact]
+ public void NullCoalesce_Is_Recognized()
+ {
+ TestSingleToken("??", CSharpSymbolType.NullCoalesce);
+ }
+
+ [Fact]
+ public void GreaterThanEqual_Is_Recognized()
+ {
+ TestSingleToken(">=", CSharpSymbolType.GreaterThanEqual);
+ }
+
+ [Fact]
+ public void EqualGreaterThan_Is_Recognized()
+ {
+ TestSingleToken("=>", CSharpSymbolType.GreaterThanEqual);
+ }
+
+ [Fact]
+ public void RightParen_Is_Recognized()
+ {
+ TestSingleToken(")", CSharpSymbolType.RightParenthesis);
+ }
+
+ [Fact]
+ public void And_Is_Recognized()
+ {
+ TestSingleToken("&", CSharpSymbolType.And);
+ }
+
+ [Fact]
+ public void DoubleColon_Is_Recognized()
+ {
+ TestSingleToken("::", CSharpSymbolType.DoubleColon);
+ }
+
+ [Fact]
+ public void PlusAssign_Is_Recognized()
+ {
+ TestSingleToken("+=", CSharpSymbolType.PlusAssign);
+ }
+
+ [Fact]
+ public void Semicolon_Is_Recognized()
+ {
+ TestSingleToken(";", CSharpSymbolType.Semicolon);
+ }
+
+ [Fact]
+ public void Tilde_Is_Recognized()
+ {
+ TestSingleToken("~", CSharpSymbolType.Tilde);
+ }
+
+ [Fact]
+ public void DoubleOr_Is_Recognized()
+ {
+ TestSingleToken("||", CSharpSymbolType.DoubleOr);
+ }
+
+ [Fact]
+ public void ModuloAssign_Is_Recognized()
+ {
+ TestSingleToken("%=", CSharpSymbolType.ModuloAssign);
+ }
+
+ [Fact]
+ public void Colon_Is_Recognized()
+ {
+ TestSingleToken(":", CSharpSymbolType.Colon);
+ }
+
+ [Fact]
+ public void Not_Is_Recognized()
+ {
+ TestSingleToken("!", CSharpSymbolType.Not);
+ }
+
+ [Fact]
+ public void DoubleAnd_Is_Recognized()
+ {
+ TestSingleToken("&&", CSharpSymbolType.DoubleAnd);
+ }
+
+ [Fact]
+ public void DivideAssign_Is_Recognized()
+ {
+ TestSingleToken("/=", CSharpSymbolType.DivideAssign);
+ }
+
+ [Fact]
+ public void Comma_Is_Recognized()
+ {
+ TestSingleToken(",", CSharpSymbolType.Comma);
+ }
+
+ [Fact]
+ public void Xor_Is_Recognized()
+ {
+ TestSingleToken("^", CSharpSymbolType.Xor);
+ }
+
+ [Fact]
+ public void Decrement_Is_Recognized()
+ {
+ TestSingleToken("--", CSharpSymbolType.Decrement);
+ }
+
+ [Fact]
+ public void MultiplyAssign_Is_Recognized()
+ {
+ TestSingleToken("*=", CSharpSymbolType.MultiplyAssign);
+ }
+
+ [Fact]
+ public void Dot_Is_Recognized()
+ {
+ TestSingleToken(".", CSharpSymbolType.Dot);
+ }
+
+ [Fact]
+ public void Or_Is_Recognized()
+ {
+ TestSingleToken("|", CSharpSymbolType.Or);
+ }
+
+ [Fact]
+ public void Increment_Is_Recognized()
+ {
+ TestSingleToken("++", CSharpSymbolType.Increment);
+ }
+
+ [Fact]
+ public void MinusAssign_Is_Recognized()
+ {
+ TestSingleToken("-=", CSharpSymbolType.MinusAssign);
+ }
+
+ [Fact]
+ public void RightShift_Is_Not_Specially_Recognized()
+ {
+ TestTokenizer(">>",
+ new CSharpSymbol(">", CSharpSymbolType.GreaterThan),
+ new CSharpSymbol(">", CSharpSymbolType.GreaterThan));
+ }
+
+ [Fact]
+ public void Hash_Is_Recognized()
+ {
+ TestSingleToken("#", CSharpSymbolType.Hash);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTest.cs
new file mode 100644
index 0000000000..c4dabc0399
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTest.cs
@@ -0,0 +1,106 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpTokenizerTest : CSharpTokenizerTestBase
+ {
+ private new CSharpSymbol IgnoreRemaining => (CSharpSymbol)base.IgnoreRemaining;
+
+ [Fact]
+ public void Next_Returns_Null_When_EOF_Reached()
+ {
+ TestTokenizer("");
+ }
+
+ [Fact]
+ public void Next_Returns_Newline_Token_For_Single_CR()
+ {
+ TestTokenizer(
+ "\r\ra",
+ new CSharpSymbol("\r", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\r", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Newline_Token_For_Single_LF()
+ {
+ TestTokenizer(
+ "\n\na",
+ new CSharpSymbol("\n", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\n", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Newline_Token_For_Single_NEL()
+ {
+ // NEL: Unicode "Next Line" U+0085
+ TestTokenizer(
+ "\u0085\u0085a",
+ new CSharpSymbol("\u0085", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\u0085", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Newline_Token_For_Single_Line_Separator()
+ {
+ // Unicode "Line Separator" U+2028
+ TestTokenizer(
+ "\u2028\u2028a",
+ new CSharpSymbol("\u2028", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\u2028", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Newline_Token_For_Single_Paragraph_Separator()
+ {
+ // Unicode "Paragraph Separator" U+2029
+ TestTokenizer(
+ "\u2029\u2029a",
+ new CSharpSymbol("\u2029", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\u2029", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Single_Newline_Token_For_CRLF()
+ {
+ TestTokenizer(
+ "\r\n\r\na",
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine),
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine),
+ IgnoreRemaining);
+ }
+
+ [Fact]
+ public void Next_Returns_Token_For_Whitespace_Characters()
+ {
+ TestTokenizer(
+ " \f\t\u000B \n ",
+ new CSharpSymbol(" \f\t\u000B ", CSharpSymbolType.WhiteSpace),
+ new CSharpSymbol("\n", CSharpSymbolType.NewLine),
+ new CSharpSymbol(" ", CSharpSymbolType.WhiteSpace));
+ }
+
+ [Fact]
+ public void Transition_Is_Recognized()
+ {
+ TestSingleToken("@", CSharpSymbolType.Transition);
+ }
+
+ [Fact]
+ public void Transition_Is_Recognized_As_SingleCharacter()
+ {
+ TestTokenizer(
+ "@(",
+ new CSharpSymbol("@", CSharpSymbolType.Transition),
+ new CSharpSymbol("(", CSharpSymbolType.LeftParenthesis));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTestBase.cs
new file mode 100644
index 0000000000..a22d0d5ef1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpTokenizerTestBase.cs
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class CSharpTokenizerTestBase : TokenizerTestBase
+ {
+ private static CSharpSymbol _ignoreRemaining = new CSharpSymbol(string.Empty, CSharpSymbolType.Unknown);
+
+ internal override object IgnoreRemaining
+ {
+ get { return _ignoreRemaining; }
+ }
+
+ internal override object CreateTokenizer(ITextDocument source)
+ {
+ return new CSharpTokenizer(source);
+ }
+
+ internal void TestSingleToken(string text, CSharpSymbolType expectedSymbolType)
+ {
+ TestTokenizer(text, new CSharpSymbol(text, expectedSymbolType));
+ }
+
+ internal void TestTokenizer(string input, params CSharpSymbol[] expectedSymbols)
+ {
+ base.TestTokenizer<CSharpSymbol, CSharpSymbolType>(input, expectedSymbols);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpVerbatimBlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpVerbatimBlockTest.cs
new file mode 100644
index 0000000000..903e68f313
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpVerbatimBlockTest.cs
@@ -0,0 +1,134 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpVerbatimBlockTest : CsHtmlCodeParserTestBase
+ {
+ private const string TestExtraKeyword = "model";
+
+ [Fact]
+ public void VerbatimBlock()
+ {
+ ParseBlockTest("@{ foo(); }",
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{")
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(" foo(); ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ Factory.MetaCode("}")
+ .Accepts(AcceptedCharactersInternal.None)
+ ));
+ }
+
+ [Fact]
+ public void InnerImplicitExpressionWithOnlySingleAtOutputsZeroLengthCodeSpan()
+ {
+ ParseBlockTest("{@}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ designTime: true,
+ expectedErrors: new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 1),
+ "}")
+ });
+ }
+
+ [Fact]
+ public void InnerImplicitExpressionDoesNotAcceptDotAfterAt()
+ {
+ ParseBlockTest("{@.}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.Code(".").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ designTime: true,
+ expectedErrors: new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 1),
+ ".")
+ });
+ }
+
+ [Fact]
+ public void InnerImplicitExpressionWithOnlySingleAtAcceptsSingleSpaceOrNewlineAtDesignTime()
+ {
+ ParseBlockTest("{" + Environment.NewLine
+ + " @" + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine + " ")
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharactersInternal.NonWhiteSpace)
+ ),
+ Factory.Code(Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ /* designTimeParser */ true,
+ RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(6 + Environment.NewLine.Length, 1, 5), Environment.NewLine.Length)));
+ }
+
+ [Fact]
+ public void InnerImplicitExpressionDoesNotAcceptTrailingNewlineInRunTimeMode()
+ {
+ ParseBlockTest("{@foo." + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo.").AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Code(Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void InnerImplicitExpressionAcceptsTrailingNewlineInDesignTimeMode()
+ {
+ ParseBlockTest("{@foo." + Environment.NewLine
+ + "}",
+ new StatementBlock(
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.EmptyCSharp()
+ .AsStatement()
+ .AutoCompleteWith(autoCompleteString: null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo.").AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Code(Environment.NewLine).AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ designTime: true);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpWhitespaceHandlingTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpWhitespaceHandlingTest.cs
new file mode 100644
index 0000000000..d33ad7d8c7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpWhitespaceHandlingTest.cs
@@ -0,0 +1,34 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class CSharpWhitespaceHandlingTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void StatementBlockDoesNotAcceptTrailingNewlineIfNewlinesAreSignificantToAncestor()
+ {
+ ParseBlockTest("@: @if (true) { }" + Environment.NewLine
+ + "}",
+ new MarkupBlock(
+ Factory.MarkupTransition()
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(" ")
+ .With(new SpanEditHandler(
+ CSharpLanguageCharacteristics.Instance.TokenizeString,
+ AcceptedCharactersInternal.Any)),
+ new StatementBlock(
+ Factory.CodeTransition()
+ .Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("if (true) { }")
+ .AsStatement()
+ ),
+ Factory.Markup(Environment.NewLine)
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CodeParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CodeParserTestBase.cs
new file mode 100644
index 0000000000..923a25a441
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CodeParserTestBase.cs
@@ -0,0 +1,79 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class CodeParserTestBase : ParserTestBase
+ {
+ internal abstract ISet<string> KeywordSet { get; }
+
+ internal override RazorSyntaxTree ParseBlock(
+ RazorLanguageVersion version,
+ string document,
+ IEnumerable<DirectiveDescriptor> directives,
+ bool designTime)
+ {
+ return ParseCodeBlock(version, document, directives, designTime);
+ }
+
+ internal void ImplicitExpressionTest(string input, params RazorDiagnostic[] errors)
+ {
+ ImplicitExpressionTest(input, AcceptedCharactersInternal.NonWhiteSpace, errors);
+ }
+
+ internal void ImplicitExpressionTest(string input, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] errors)
+ {
+ ImplicitExpressionTest(input, input, acceptedCharacters, errors);
+ }
+
+ internal void ImplicitExpressionTest(string input, string expected, params RazorDiagnostic[] errors)
+ {
+ ImplicitExpressionTest(input, expected, AcceptedCharactersInternal.NonWhiteSpace, errors);
+ }
+
+ internal override void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
+ {
+ SingleSpanBlockTest(document, blockKind, spanType, acceptedCharacters, expectedError: null);
+ }
+
+ internal override void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters = AcceptedCharactersInternal.Any)
+ {
+ SingleSpanBlockTest(document, spanContent, blockKind, spanType, acceptedCharacters, expectedErrors: null);
+ }
+
+ internal override void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, params RazorDiagnostic[] expectedError)
+ {
+ SingleSpanBlockTest(document, document, blockKind, spanType, expectedError);
+ }
+
+ internal override void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, params RazorDiagnostic[] expectedErrors)
+ {
+ SingleSpanBlockTest(document, spanContent, blockKind, spanType, AcceptedCharactersInternal.Any, expectedErrors ?? new RazorDiagnostic[0]);
+ }
+
+ internal override void SingleSpanBlockTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedError)
+ {
+ SingleSpanBlockTest(document, document, blockKind, spanType, acceptedCharacters, expectedError);
+ }
+
+ internal override void SingleSpanBlockTest(string document, string spanContent, BlockKindInternal blockKind, SpanKindInternal spanType, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] expectedErrors)
+ {
+ var b = CreateSimpleBlockAndSpan(spanContent, blockKind, spanType, acceptedCharacters);
+ ParseBlockTest(document, b, expectedErrors ?? new RazorDiagnostic[0]);
+ }
+
+ internal void ImplicitExpressionTest(string input, string expected, AcceptedCharactersInternal acceptedCharacters, params RazorDiagnostic[] errors)
+ {
+ var factory = CreateSpanFactory();
+ ParseBlockTest(SyntaxConstants.TransitionString + input,
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code(expected)
+ .AsImplicitExpression(KeywordSet)
+ .Accepts(acceptedCharacters)),
+ errors);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlCodeParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlCodeParserTestBase.cs
new file mode 100644
index 0000000000..db0f3d845a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlCodeParserTestBase.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class CsHtmlCodeParserTestBase : CodeParserTestBase
+ {
+ internal override ISet<string> KeywordSet
+ {
+ get { return CSharpCodeParser.DefaultKeywords; }
+ }
+
+ internal override BlockFactory CreateBlockFactory()
+ {
+ return new BlockFactory(Factory ?? CreateSpanFactory());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlMarkupParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlMarkupParserTestBase.cs
new file mode 100644
index 0000000000..a643ea73af
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CsHtmlMarkupParserTestBase.cs
@@ -0,0 +1,20 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class CsHtmlMarkupParserTestBase : MarkupParserTestBase
+ {
+ internal override ISet<string> KeywordSet
+ {
+ get { return CSharpCodeParser.DefaultKeywords; }
+ }
+
+ internal override BlockFactory CreateBlockFactory()
+ {
+ return new BlockFactory(Factory ?? CreateSpanFactory());
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveCSharpTokenizerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveCSharpTokenizerTest.cs
new file mode 100644
index 0000000000..dcbbd2b1ef
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveCSharpTokenizerTest.cs
@@ -0,0 +1,47 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class DirectiveCSharpTokenizerTest : CSharpTokenizerTestBase
+ {
+ [Fact]
+ public void Next_ReturnsNull_AfterTokenizingFirstDirective()
+ {
+ TestTokenizer(
+ "\r\n @something \r\n @this is ignored",
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine),
+ new CSharpSymbol(" ", CSharpSymbolType.WhiteSpace),
+ new CSharpSymbol("@", CSharpSymbolType.Transition),
+ new CSharpSymbol("something", CSharpSymbolType.Identifier),
+ new CSharpSymbol(" ", CSharpSymbolType.WhiteSpace),
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine));
+ }
+
+ [Fact]
+ public void Next_IncludesComments_ReturnsNull_AfterTokenizingFirstDirective()
+ {
+ TestTokenizer(
+ "@*included*@\r\n @something \"value\"\r\n @this is ignored",
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol("included", CSharpSymbolType.RazorComment),
+ new CSharpSymbol("*", CSharpSymbolType.RazorCommentStar),
+ new CSharpSymbol("@", CSharpSymbolType.RazorCommentTransition),
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine),
+ new CSharpSymbol(" ", CSharpSymbolType.WhiteSpace),
+ new CSharpSymbol("@", CSharpSymbolType.Transition),
+ new CSharpSymbol("something", CSharpSymbolType.Identifier),
+ new CSharpSymbol(" ", CSharpSymbolType.WhiteSpace),
+ new CSharpSymbol("\"value\"", CSharpSymbolType.StringLiteral),
+ new CSharpSymbol("\r\n", CSharpSymbolType.NewLine));
+ }
+
+ internal override object CreateTokenizer(ITextDocument source)
+ {
+ return new DirectiveCSharpTokenizer(source);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveHtmlTokenizerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveHtmlTokenizerTest.cs
new file mode 100644
index 0000000000..b75874b681
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DirectiveHtmlTokenizerTest.cs
@@ -0,0 +1,41 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class DirectiveHtmlTokenizerTest : HtmlTokenizerTestBase
+ {
+ [Fact]
+ public void Next_ReturnsNull_WhenHtmlIsSeen()
+ {
+ TestTokenizer(
+ "\r\n <div>Ignored</div>",
+ new HtmlSymbol("\r\n", HtmlSymbolType.NewLine),
+ new HtmlSymbol(" ", HtmlSymbolType.WhiteSpace),
+ new HtmlSymbol("<", HtmlSymbolType.OpenAngle));
+ }
+
+ [Fact]
+ public void Next_IncludesRazorComments_ReturnsNull_WhenHtmlIsSeen()
+ {
+ TestTokenizer(
+ "\r\n @*included*@ <div>Ignored</div>",
+ new HtmlSymbol("\r\n", HtmlSymbolType.NewLine),
+ new HtmlSymbol(" ", HtmlSymbolType.WhiteSpace),
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol("included", HtmlSymbolType.RazorComment),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition),
+ new HtmlSymbol(" ", HtmlSymbolType.WhiteSpace),
+ new HtmlSymbol("<", HtmlSymbolType.OpenAngle));
+ }
+
+ internal override object CreateTokenizer(ITextDocument source)
+ {
+ return new DirectiveHtmlTokenizer(source);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DisposableActionTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DisposableActionTest.cs
new file mode 100644
index 0000000000..8f14f832c4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/DisposableActionTest.cs
@@ -0,0 +1,25 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class DisposableActionTest
+ {
+ [Fact]
+ public void ActionIsExecutedOnDispose()
+ {
+ // Arrange
+ var called = false;
+ var action = new DisposableAction(() => { called = true; });
+
+ // Act
+ action.Dispose();
+
+ // Assert
+ Assert.True(called, "The action was not run when the DisposableAction was disposed");
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ExceptionHelpers.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ExceptionHelpers.cs
new file mode 100644
index 0000000000..c5ae54dea8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/ExceptionHelpers.cs
@@ -0,0 +1,16 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public static class ExceptionHelpers
+ {
+ public static void ValidateArgumentException(string parameterName, string expectedMessage, ArgumentException exception)
+ {
+ Assert.Equal(string.Format("{0}{1}Parameter name: {2}", expectedMessage, Environment.NewLine, parameterName), exception.Message);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlAttributeTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlAttributeTest.cs
new file mode 100644
index 0000000000..64686c9fbb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlAttributeTest.cs
@@ -0,0 +1,707 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlAttributeTest : CsHtmlMarkupParserTestBase
+ {
+ public static TheoryData SymbolBoundAttributeNames
+ {
+ get
+ {
+ return new TheoryData<string>
+ {
+ "[item]",
+ "[(item,",
+ "(click)",
+ "(^click)",
+ "*something",
+ "#local",
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(SymbolBoundAttributeNames))]
+ public void SymbolBoundAttributes_BeforeEqualWhitespace(string attributeName)
+ {
+ // Arrange
+ var attributeNameLength = attributeName.Length;
+ var newlineLength = Environment.NewLine.Length;
+ var prefixLocation1 = new SourceLocation(
+ absoluteIndex: 2,
+ lineIndex: 0,
+ characterIndex: 2);
+ var suffixLocation1 = new SourceLocation(
+ absoluteIndex: 8 + newlineLength + attributeNameLength,
+ lineIndex: 1,
+ characterIndex: 5);
+ var valueLocation1 = new SourceLocation(
+ absoluteIndex: 5 + attributeNameLength + newlineLength,
+ lineIndex: 1,
+ characterIndex: 2);
+ var prefixLocation2 = SourceLocationTracker.Advance(suffixLocation1, "'");
+ var suffixLocation2 = new SourceLocation(
+ absoluteIndex: 15 + attributeNameLength * 2 + newlineLength * 2,
+ lineIndex: 2,
+ characterIndex: 4);
+ var valueLocation2 = new SourceLocation(
+ absoluteIndex: 12 + attributeNameLength * 2 + newlineLength * 2,
+ lineIndex: 2,
+ characterIndex: 1);
+
+ // Act & Assert
+ ParseBlockTest(
+ $"<a {attributeName}{Environment.NewLine}='Foo'\t{attributeName}={Environment.NewLine}'Bar' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ attributeName,
+ prefix: new LocationTagged<string>(
+ $" {attributeName}{Environment.NewLine}='", prefixLocation1),
+ suffix: new LocationTagged<string>("'", suffixLocation1)),
+ Factory.Markup($" {attributeName}{Environment.NewLine}='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, valueLocation1),
+ value: new LocationTagged<string>("Foo", valueLocation1))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ attributeName,
+ prefix: new LocationTagged<string>(
+ $"\t{attributeName}={Environment.NewLine}'", prefixLocation2),
+ suffix: new LocationTagged<string>("'", suffixLocation2)),
+ Factory.Markup($"\t{attributeName}={Environment.NewLine}'").With(SpanChunkGenerator.Null),
+ Factory.Markup("Bar").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, valueLocation2),
+ value: new LocationTagged<string>("Bar", valueLocation2))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Theory]
+ [MemberData(nameof(SymbolBoundAttributeNames))]
+ public void SymbolBoundAttributes_Whitespace(string attributeName)
+ {
+ // Arrange
+ var attributeNameLength = attributeName.Length;
+ var newlineLength = Environment.NewLine.Length;
+ var prefixLocation1 = new SourceLocation(
+ absoluteIndex: 2,
+ lineIndex: 0,
+ characterIndex: 2);
+ var suffixLocation1 = new SourceLocation(
+ absoluteIndex: 10 + newlineLength + attributeNameLength,
+ lineIndex: 1,
+ characterIndex: 7 + attributeNameLength);
+ var valueLocation1 = new SourceLocation(
+ absoluteIndex: 7 + attributeNameLength + newlineLength,
+ lineIndex: 1,
+ characterIndex: 4 + attributeNameLength);
+ var prefixLocation2 = SourceLocationTracker.Advance(suffixLocation1, "'");
+ var suffixLocation2 = new SourceLocation(
+ absoluteIndex: 17 + attributeNameLength * 2 + newlineLength * 2,
+ lineIndex: 2,
+ characterIndex: 5 + attributeNameLength);
+ var valueLocation2 = new SourceLocation(
+ absoluteIndex: 14 + attributeNameLength * 2 + newlineLength * 2,
+ lineIndex: 2,
+ characterIndex: 2 + attributeNameLength);
+
+ // Act & Assert
+ ParseBlockTest(
+ $"<a {Environment.NewLine} {attributeName}='Foo'\t{Environment.NewLine}{attributeName}='Bar' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ attributeName,
+ prefix: new LocationTagged<string>(
+ $" {Environment.NewLine} {attributeName}='", prefixLocation1),
+ suffix: new LocationTagged<string>("'", suffixLocation1)),
+ Factory.Markup($" {Environment.NewLine} {attributeName}='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, valueLocation1),
+ value: new LocationTagged<string>("Foo", valueLocation1))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ attributeName,
+ prefix: new LocationTagged<string>(
+ $"\t{Environment.NewLine}{attributeName}='", prefixLocation2),
+ suffix: new LocationTagged<string>("'", suffixLocation2)),
+ Factory.Markup($"\t{Environment.NewLine}{attributeName}='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Bar").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, valueLocation2),
+ value: new LocationTagged<string>("Bar", valueLocation2))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Theory]
+ [MemberData(nameof(SymbolBoundAttributeNames))]
+ public void SymbolBoundAttributes(string attributeName)
+ {
+ // Arrange
+ var attributeNameLength = attributeName.Length;
+ var suffixLocation = 8 + attributeNameLength;
+ var valueLocation = 5 + attributeNameLength;
+
+ // Act & Assert
+ ParseBlockTest($"<a {attributeName}='Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ attributeName,
+ prefix: new LocationTagged<string>($" {attributeName}='", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", suffixLocation, 0, suffixLocation)),
+ Factory.Markup($" {attributeName}='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, valueLocation, 0, valueLocation),
+ value: new LocationTagged<string>("Foo", valueLocation, 0, valueLocation))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void SimpleLiteralAttribute()
+ {
+ ParseBlockTest("<a href='Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 12, 0, 12)),
+ Factory.Markup(" href='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 9, 0, 9), value: new LocationTagged<string>("Foo", 9, 0, 9))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void SimpleLiteralAttributeWithWhitespaceSurroundingEquals()
+ {
+ ParseBlockTest("<a href \f\r\n= \t\n'Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "href",
+ prefix: new LocationTagged<string>(" href \f\r\n= \t\n'", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", 19, 2, 4)),
+ Factory.Markup(" href \f\r\n= \t\n'").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 2, 1), value: new LocationTagged<string>("Foo", 16, 2, 1))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void DynamicAttributeWithWhitespaceSurroundingEquals()
+ {
+ ParseBlockTest("<a href \n= \r\n'@Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "href",
+ prefix: new LocationTagged<string>(" href \n= \r\n'", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", 18, 2, 5)),
+ Factory.Markup(" href \n= \r\n'").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 14, 2, 1), 14, 2, 1),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("Foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void MultiPartLiteralAttribute()
+ {
+ ParseBlockTest("<a href='Foo Bar Baz' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 20, 0, 20)),
+ Factory.Markup(" href='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 9, 0, 9), value: new LocationTagged<string>("Foo", 9, 0, 9))),
+ Factory.Markup(" Bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(" ", 12, 0, 12), value: new LocationTagged<string>("Bar", 13, 0, 13))),
+ Factory.Markup(" Baz").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(" ", 16, 0, 16), value: new LocationTagged<string>("Baz", 17, 0, 17))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void DoubleQuotedLiteralAttribute()
+ {
+ ParseBlockTest("<a href=\"Foo Bar Baz\" />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href=\"", 2, 0, 2), suffix: new LocationTagged<string>("\"", 20, 0, 20)),
+ Factory.Markup(" href=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 9, 0, 9), value: new LocationTagged<string>("Foo", 9, 0, 9))),
+ Factory.Markup(" Bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(" ", 12, 0, 12), value: new LocationTagged<string>("Bar", 13, 0, 13))),
+ Factory.Markup(" Baz").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(" ", 16, 0, 16), value: new LocationTagged<string>("Baz", 17, 0, 17))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void NewLinePrecedingAttribute()
+ {
+ ParseBlockTest("<a\r\nhref='Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "href",
+ prefix: new LocationTagged<string>("\r\nhref='", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", 13, 1, 9)),
+ Factory.Markup("\r\nhref='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 10, 1, 6),
+ value: new LocationTagged<string>("Foo", 10, 1, 6))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void NewLineBetweenAttributes()
+ {
+ ParseBlockTest("<a\nhref='Foo'\r\nabcd='Bar' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(
+ name: "href",
+ prefix: new LocationTagged<string>("\nhref='", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", 12, 1, 9)),
+ Factory.Markup("\nhref='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 9, 1, 6),
+ value: new LocationTagged<string>("Foo", 9, 1, 6))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "abcd",
+ prefix: new LocationTagged<string>("\r\nabcd='", 13, 1, 10),
+ suffix: new LocationTagged<string>("'", 24, 2, 9)),
+ Factory.Markup("\r\nabcd='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Bar").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 21, 2, 6),
+ value: new LocationTagged<string>("Bar", 21, 2, 6))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void WhitespaceAndNewLinePrecedingAttribute()
+ {
+ ParseBlockTest("<a \t\r\nhref='Foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "href",
+ prefix: new LocationTagged<string>(" \t\r\nhref='", 2, 0, 2),
+ suffix: new LocationTagged<string>("'", 15, 1, 9)),
+ Factory.Markup(" \t\r\nhref='").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 12, 1, 6),
+ value: new LocationTagged<string>("Foo", 12, 1, 6))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void UnquotedLiteralAttribute()
+ {
+ ParseBlockTest("<a href=Foo Bar Baz />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href=", 2, 0, 2), suffix: new LocationTagged<string>(string.Empty, 11, 0, 11)),
+ Factory.Markup(" href=").With(SpanChunkGenerator.Null),
+ Factory.Markup("Foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 8, 0, 8), value: new LocationTagged<string>("Foo", 8, 0, 8)))),
+ new MarkupBlock(Factory.Markup(" Bar")),
+ new MarkupBlock(Factory.Markup(" Baz")),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void SimpleExpressionAttribute()
+ {
+ ParseBlockTest("<a href='@foo' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 13, 0, 13)),
+ Factory.Markup(" href='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), 9, 0, 9),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void MultiValueExpressionAttribute()
+ {
+ ParseBlockTest("<a href='@foo bar @baz' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 22, 0, 22)),
+ Factory.Markup(" href='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), 9, 0, 9),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup(" bar").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 13, 0, 13), new LocationTagged<string>("bar", 14, 0, 14))),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(" ", 17, 0, 17), 18, 0, 18),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("baz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void VirtualPathAttributesWorkWithConditionalAttributes()
+ {
+ ParseBlockTest("<a href='@foo ~/Foo/Bar' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "href", prefix: new LocationTagged<string>(" href='", 2, 0, 2), suffix: new LocationTagged<string>("'", 23, 0, 23)),
+ Factory.Markup(" href='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), 9, 0, 9),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup(" ~/Foo/Bar")
+ .With(new LiteralAttributeChunkGenerator(
+ new LocationTagged<string>(" ", 13, 0, 13),
+ new LocationTagged<string>("~/Foo/Bar", 14, 0, 14))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void UnquotedAttributeWithCodeWithSpacesInBlock()
+ {
+ ParseBlockTest("<input value=@foo />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<input"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "value", prefix: new LocationTagged<string>(" value=", 6, 0, 6), suffix: new LocationTagged<string>(string.Empty, 17, 0, 17)),
+ Factory.Markup(" value=").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 13, 0, 13), 13, 0, 13),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void UnquotedAttributeWithCodeWithSpacesInDocument()
+ {
+ ParseDocumentTest("<input value=@foo />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<input"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "value", prefix: new LocationTagged<string>(" value=", 6, 0, 6), suffix: new LocationTagged<string>(string.Empty, 17, 0, 17)),
+ Factory.Markup(" value=").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 13, 0, 13), 13, 0, 13),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))),
+ Factory.Markup(" />"))));
+ }
+
+ [Fact]
+ public void ConditionalAttributeCollapserDoesNotRewriteEscapedTransitions()
+ {
+ // Act
+ var results = ParseDocument("<span foo='@@' />");
+ var attributeCollapser = new ConditionalAttributeCollapser();
+ var rewritten = attributeCollapser.Rewrite(results.Root);
+
+ // Assert
+ EvaluateParseTree(rewritten,
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 13, 0, 13)),
+ Factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ Factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />"))));
+ }
+
+ [Fact]
+ public void ConditionalAttributesDoNotCreateExtraDataForEntirelyLiteralAttribute()
+ {
+ // Arrange
+ const string code =
+ @"<div class=""sidebar"">
+ <h1>Title</h1>
+ <p>
+ As the author, you can <a href=""/Photo/Edit/photoId"">edit</a>
+ or <a href=""/Photo/Remove/photoId"">remove</a> this photo.
+ </p>
+ <dl>
+ <dt class=""description"">Description</dt>
+ <dd class=""description"">
+ The uploader did not provide a description for this photo.
+ </dd>
+ <dt class=""uploaded-by"">Uploaded by</dt>
+ <dd class=""uploaded-by""><a href=""/User/View/user.UserId"">user.DisplayName</a></dd>
+ <dt class=""upload-date"">Upload date</dt>
+ <dd class=""upload-date"">photo.UploadDate</dd>
+ <dt class=""part-of-gallery"">Gallery</dt>
+ <dd><a href=""/View/gallery.Id"" title=""View gallery.Name gallery"">gallery.Name</a></dd>
+ <dt class=""tags"">Tags</dt>
+ <dd class=""tags"">
+ <ul class=""tags"">
+ <li>This photo has no tags.</li>
+ </ul>
+ <a href=""/Photo/EditTags/photoId"">edit tags</a>
+ </dd>
+ </dl>
+
+ <p>
+ <a class=""download"" href=""/Photo/Full/photoId"" title=""Download: (photo.FileTitle + photo.FileExtension)"">Download full photo</a> ((photo.FileSize / 1024) KB)
+ </p>
+</div>
+<div class=""main"">
+ <img class=""large-photo"" alt=""photo.FileTitle"" src=""/Photo/Thumbnail"" />
+ <h2>Nobody has commented on this photo</h2>
+ <ol class=""comments"">
+ <li>
+ <h3 class=""comment-header"">
+ <a href=""/User/View/comment.UserId"" title=""View comment.DisplayName's profile"">comment.DisplayName</a> commented at comment.CommentDate:
+ </h3>
+ <p class=""comment-body"">comment.CommentText</p>
+ </li>
+ </ol>
+
+ <form method=""post"" action="""">
+ <fieldset id=""addComment"">
+ <legend>Post new comment</legend>
+ <ol>
+ <li>
+ <label for=""newComment"">Comment</label>
+ <textarea id=""newComment"" name=""newComment"" title=""Your comment"" rows=""6"" cols=""70""></textarea>
+ </li>
+ </ol>
+ <p class=""form-actions"">
+ <input type=""submit"" title=""Add comment"" value=""Add comment"" />
+ </p>
+ </fieldset>
+ </form>
+</div>";
+
+ // Act
+ var results = ParseDocument(code);
+ var attributeCollapser = new ConditionalAttributeCollapser();
+ var rewritten = attributeCollapser.Rewrite(results.Root);
+
+ // Assert
+ Assert.Equal(rewritten.Children.Count(), results.Root.Children.Count());
+ }
+
+ [Fact]
+ public void ConditionalAttributesAreEnabledForDataAttributesWithExperimentalFlag()
+ {
+ ParseBlockTest(
+ RazorLanguageVersion.Experimental,
+ "<span data-foo='@foo'></span>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("data-foo", new LocationTagged<string>(" data-foo='", 5, 0, 5), new LocationTagged<string>("'", 20, 0, 20)),
+ Factory.Markup(" data-foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 16, 0, 16), 16, 0, 16),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</span>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ConditionalAttributesAreDisabledForDataAttributesInBlock()
+ {
+ ParseBlockTest("<span data-foo='@foo'></span>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ Factory.Markup(" data-foo='"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'")),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</span>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ConditionalAttributesWithWeirdSpacingAreDisabledForDataAttributesInBlock()
+ {
+ ParseBlockTest("<span data-foo = '@foo'></span>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ Factory.Markup(" data-foo = '"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'")),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</span>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ConditionalAttributesAreDisabledForDataAttributesInDocument()
+ {
+ ParseDocumentTest("<span data-foo='@foo'></span>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ Factory.Markup(" data-foo='"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'")),
+ Factory.Markup(">")),
+ new MarkupTagBlock(
+ Factory.Markup("</span>"))));
+ }
+
+ [Fact]
+ public void ConditionalAttributesWithWeirdSpacingAreDisabledForDataAttributesInDocument()
+ {
+ ParseDocumentTest("<span data-foo=@foo ></span>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ Factory.Markup(" data-foo="),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup(" >")),
+ new MarkupTagBlock(
+ Factory.Markup("</span>"))));
+ }
+
+ private class EmptyTestDocument : ITextDocument
+ {
+ public int Length
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public SourceLocation Location
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public int Position
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public int Peek()
+ {
+ throw new NotImplementedException();
+ }
+
+ public int Read()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs
new file mode 100644
index 0000000000..3abd53b105
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlBlockTest.cs
@@ -0,0 +1,657 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlBlockTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void ParseBlockHandlesUnbalancedTripleDashHTMLComments()
+ {
+ ParseDocumentTest(
+@"@{
+ <!-- Hello, I'm a comment that shouldn't break razor --->
+}",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine).AsStatement().AutoCompleteWith(null),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.HtmlCommentBlock(" Hello, I'm a comment that shouldn't break razor -"),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()),
+ new RazorDiagnostic[0]);
+ }
+
+ [Fact]
+ public void ParseBlockHandlesOpenAngleAtEof()
+ {
+ ParseDocumentTest("@{" + Environment.NewLine
+ + "<",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine)
+ .AsStatement()
+ .AutoCompleteWith("}"),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<"))))),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
+ }
+
+ [Fact]
+ public void ParseBlockHandlesOpenAngleWithProperTagFollowingIt()
+ {
+ ParseDocumentTest("@{" + Environment.NewLine
+ + "<" + Environment.NewLine
+ + "</html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code(Environment.NewLine)
+ .AsStatement()
+ .AutoCompleteWith("}"),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<" + Environment.NewLine))
+ ),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("</html>").Accepts(AcceptedCharactersInternal.None))
+ ),
+ Factory.EmptyCSharp().AsStatement()
+ )
+ ),
+ designTime: true,
+ expectedErrors: new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(new SourceLocation(5 + Environment.NewLine.Length * 2, 2, 2), contentLength: 4), "html"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ });
+ }
+
+ [Fact]
+ public void TagWithoutCloseAngleDoesNotTerminateBlock()
+ {
+ ParseBlockTest("< " + Environment.NewLine
+ + " ",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup($"< {Environment.NewLine} "))),
+ designTime: true,
+ expectedErrors: RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), string.Empty));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsStartAndEndTagsToDifferInCase()
+ {
+ ParseBlockTest("<li><p>Foo</P></lI>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</P>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</lI>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockReadsToEndOfLineIfFirstCharacterAfterTransitionIsColon()
+ {
+ ParseBlockTest("@:<li>Foo Bar Baz" + Environment.NewLine
+ + "bork",
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("<li>Foo Bar Baz" + Environment.NewLine)
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockStopsParsingSingleLineBlockAtEOFIfNoEOLReached()
+ {
+ ParseBlockTest("@:foo bar",
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(@"foo bar")
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockStopsAtMatchingCloseTagToStartTag()
+ {
+ ParseBlockTest("<a><b></b></a><c></c>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<b>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</b>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</a>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockParsesUntilMatchingEndTagIfFirstNonWhitespaceCharacterIsStartTag()
+ {
+ ParseBlockTest("<baz><boz><biz></biz></boz></baz>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<baz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<boz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<biz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</biz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</boz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</baz>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsUnclosedTagsAsLongAsItCanRecoverToAnExpectedEndTag()
+ {
+ ParseBlockTest("<foo><bar><baz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<baz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockWithSelfClosingTagJustEmitsTag()
+ {
+ ParseBlockTest("<foo />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo />").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockCanHandleSelfClosingTagsWithinBlock()
+ {
+ ParseBlockTest("<foo><bar /></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar />").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsTagsWithAttributes()
+ {
+ ParseBlockTest("<foo bar=\"baz\"><biz><boz zoop=zork/></biz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("bar", new LocationTagged<string>(" bar=\"", 4, 0, 4), new LocationTagged<string>("\"", 13, 0, 13)),
+ Factory.Markup(" bar=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup("baz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 10, 0, 10), new LocationTagged<string>("baz", 10, 0, 10))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<biz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<boz"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("zoop", new LocationTagged<string>(" zoop=", 24, 0, 24), new LocationTagged<string>(string.Empty, 34, 0, 34)),
+ Factory.Markup(" zoop=").With(SpanChunkGenerator.Null),
+ Factory.Markup("zork").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 30, 0, 30), new LocationTagged<string>("zork", 30, 0, 30)))),
+ Factory.Markup("/>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</biz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsCloseAngleBracketInAttributeValueIfDoubleQuoted()
+ {
+ ParseBlockTest("<foo><bar baz=\">\" /></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz=\"", 9, 0, 9), new LocationTagged<string>("\"", 16, 0, 16)),
+ Factory.Markup(" baz=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup(">").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>(">", 15, 0, 15))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsCloseAngleBracketInAttributeValueIfSingleQuoted()
+ {
+ ParseBlockTest("<foo><bar baz=\'>\' /></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz='", 9, 0, 9), new LocationTagged<string>("'", 16, 0, 16)),
+ Factory.Markup(" baz='").With(SpanChunkGenerator.Null),
+ Factory.Markup(">").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>(">", 15, 0, 15))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsSlashInAttributeValueIfDoubleQuoted()
+ {
+ ParseBlockTest("<foo><bar baz=\"/\"></bar></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz=\"", 9, 0, 9), new LocationTagged<string>("\"", 16, 0, 16)),
+ Factory.Markup(" baz=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup("/").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("/", 15, 0, 15))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockAllowsSlashInAttributeValueIfSingleQuoted()
+ {
+ ParseBlockTest("<foo><bar baz=\'/\'></bar></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz='", 9, 0, 9), new LocationTagged<string>("'", 16, 0, 16)),
+ Factory.Markup(" baz='").With(SpanChunkGenerator.Null),
+ Factory.Markup("/").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("/", 15, 0, 15))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesAtEOF()
+ {
+ ParseBlockTest("<foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None))),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCommentAsBlock()
+ {
+ ParseBlockTest("<!-- foo -->", new MarkupBlock(BlockFactory.HtmlCommentBlock(" foo ")));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCommentWithExtraDashAsBlock()
+ {
+ ParseBlockTest("<!-- foo --->", new MarkupBlock(BlockFactory.HtmlCommentBlock(" foo -")));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCommentWithinBlock()
+ {
+ ParseBlockTest("<foo>bar<!-- zoop -->baz</foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("bar"),
+ BlockFactory.HtmlCommentBlock(" zoop "),
+ Factory.Markup("baz").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ public static TheoryData HtmlCommentSupportsMultipleDashesData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<div><!--- Hello World ---></div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.HtmlCommentBlock("- Hello World -"),
+ new MarkupTagBlock(
+ factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
+ },
+ {
+ "<div><!---- Hello World ----></div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.HtmlCommentBlock("-- Hello World --"),
+ new MarkupTagBlock(
+ factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
+ },
+ {
+ "<div><!----- Hello World -----></div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.HtmlCommentBlock("--- Hello World ---"),
+ new MarkupTagBlock(
+ factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
+ },
+ {
+ "<div><!----- Hello < --- > World </div> -----></div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.HtmlCommentBlock("--- Hello < --- > World </div> ---"),
+ new MarkupTagBlock(
+ factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(HtmlCommentSupportsMultipleDashesData))]
+ public void HtmlCommentSupportsMultipleDashes(string documentContent, object expectedOutput)
+ {
+ FixupSpans = true;
+
+ ParseBlockTest(documentContent, (MarkupBlock)expectedOutput);
+ }
+
+ [Fact]
+ public void ParseBlockProperlyBalancesCommentStartAndEndTags()
+ {
+ ParseBlockTest("<!--<foo></bar>-->", new MarkupBlock(BlockFactory.HtmlCommentBlock("<foo></bar>")));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesAtEOFWhenParsingComment()
+ {
+ ParseBlockTest(
+ "<!--<foo>",
+ new MarkupBlock(
+ Factory.Markup("<!--<foo>").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockOnlyTerminatesCommentOnFullEndSequence()
+ {
+ ParseBlockTest("<!--<foo>--</bar>-->", new MarkupBlock(BlockFactory.HtmlCommentBlock("<foo>--</bar>")));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesCommentAtFirstOccurrenceOfEndSequence()
+ {
+ ParseBlockTest("<foo><!--<foo></bar-->--></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ BlockFactory.HtmlCommentBlock("<foo></bar"),
+ Factory.Markup("-->").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockTreatsMalformedTagsAsContent()
+ {
+ ParseBlockTest("<foo></!-- bar --></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</!-- bar -->").Accepts(AcceptedCharactersInternal.None))),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
+ }
+
+
+ [Fact]
+ public void ParseBlockParsesSGMLDeclarationAsEmptyTag()
+ {
+ ParseBlockTest("<foo><!DOCTYPE foo bar baz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<!DOCTYPE foo bar baz>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesSGMLDeclarationAtFirstCloseAngle()
+ {
+ ParseBlockTest("<foo><!DOCTYPE foo bar> baz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<!DOCTYPE foo bar>").Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" baz>"),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockParsesXMLProcessingInstructionAsEmptyTag()
+ {
+ ParseBlockTest("<foo><?xml foo bar baz?></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<?xml foo bar baz?>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockTerminatesXMLProcessingInstructionAtQuestionMarkCloseAnglePair()
+ {
+ ParseBlockTest("<foo><?xml foo bar baz?> baz</foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<?xml foo bar baz?>").Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotTerminateXMLProcessingInstructionAtCloseAngleUnlessPreceededByQuestionMark()
+ {
+ ParseBlockTest("<foo><?xml foo bar> baz?></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<?xml foo bar> baz?>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsScriptTagsWithLessThanSignsInThem()
+ {
+ ParseBlockTest(@"<script>if(foo<bar) { alert(""baz"");)</script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(@"if(foo<bar) { alert(""baz"");)"),
+ new MarkupTagBlock(
+ Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsScriptTagsWithSpacedLessThanSignsInThem()
+ {
+ ParseBlockTest(@"<script>if(foo < bar) { alert(""baz"");)</script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(@"if(foo < bar) { alert(""baz"");)"),
+ new MarkupTagBlock(
+ Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockAcceptsEmptyTextTag()
+ {
+ ParseBlockTest("<text/>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text/>"))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockAcceptsTextTagAsOuterTagButDoesNotRender()
+ {
+ ParseBlockTest("<text>Foo Bar <foo> Baz</text> zoop",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ Factory.Markup("Foo Bar ").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" Baz"),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>"))));
+ }
+
+ [Fact]
+ public void ParseBlockRendersLiteralTextTagIfDoubled()
+ {
+ ParseBlockTest("<text><text>Foo Bar <foo> Baz</text></text> zoop",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ new MarkupTagBlock(
+ Factory.Markup("<text>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo Bar "),
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" Baz"),
+ new MarkupTagBlock(
+ Factory.Markup("</text>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>"))));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotConsiderPsuedoTagWithinMarkupBlock()
+ {
+ ParseBlockTest("<foo><text><bar></bar></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<text>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<bar>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
+ ));
+ }
+
+ [Fact]
+ public void ParseBlockStopsParsingMidEmptyTagIfEOFReached()
+ {
+ ParseBlockTest("<br/",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<br/"))),
+ RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 2), "br"));
+ }
+
+ [Fact]
+ public void ParseBlockCorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement()
+ {
+ ParseBlockTest("<div>Foo @if(true) {} Bar</div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Foo "),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true) {}").AsStatement()),
+ Factory.Markup(" Bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockIgnoresTagsInContentsOfScriptTag()
+ {
+ ParseBlockTest(@"<script>foo<bar baz='@boz'></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("foo<bar baz='"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'>"),
+ new MarkupTagBlock(
+ Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs
new file mode 100644
index 0000000000..b7f5eeb87d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs
@@ -0,0 +1,803 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlDocumentTest : CsHtmlMarkupParserTestBase
+ {
+ private static readonly TestFile Nested1000 = TestFile.Create("TestFiles/nested-1000.html", typeof(HtmlDocumentTest));
+
+ [Fact]
+ public void ParseDocument_NestedCodeBlockWithMarkupSetsDotAsMarkup()
+ {
+ ParseDocumentTest("@if (true) { @if(false) { <div>@something.</div> } }",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if (true) { ").AsStatement(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(false) {").AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<div>", AcceptedCharactersInternal.None),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("something")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("."),
+ BlockFactory.MarkupTagBlock("</div>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code("}").AsStatement()),
+ Factory.Code(" }").AsStatement())));
+ }
+
+ [Fact]
+ public void ParseDocumentOutputsEmptyBlockWithEmptyMarkupSpanIfContentIsEmptyString()
+ {
+ ParseDocumentTest(string.Empty, new MarkupBlock(Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseDocumentOutputsWhitespaceOnlyContentAsSingleWhitespaceMarkupSpan()
+ {
+ SingleSpanDocumentTest(" ", BlockKindInternal.Markup, SpanKindInternal.Markup);
+ }
+
+ [Fact]
+ public void ParseDocumentAcceptsSwapTokenAtEndOfFileAndOutputsZeroLengthCodeSpan()
+ {
+ ParseDocumentTest("@",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.EmptyHtml()),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseDocumentCorrectlyHandlesOddlySpacedHTMLElements()
+ {
+ ParseDocumentTest("<div ><p class = 'bar'> Foo </p></div >",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<div >"),
+ new MarkupTagBlock(
+ Factory.Markup("<p"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "class", prefix: new LocationTagged<string>(" class = '", 8, 0, 8), suffix: new LocationTagged<string>("'", 21, 0, 21)),
+ Factory.Markup(" class = '").With(SpanChunkGenerator.Null),
+ Factory.Markup("bar").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 18, 0, 18), value: new LocationTagged<string>("bar", 18, 0, 18))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">")),
+ Factory.Markup(" Foo "),
+ BlockFactory.MarkupTagBlock("</p>"),
+ BlockFactory.MarkupTagBlock("</div >")));
+ }
+
+ [Fact]
+ public void ParseDocumentCorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement()
+ {
+ ParseDocumentTest("<div>Foo @if(true) {} Bar</div>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<div>"),
+ Factory.Markup("Foo "),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true) {}").AsStatement()),
+ Factory.Markup(" Bar"),
+ BlockFactory.MarkupTagBlock("</div>")));
+ }
+
+ [Fact]
+ public void ParseDocumentWithinSectionDoesNotCreateDocumentLevelSpan()
+ {
+ ParseDocumentTest("@section Foo {" + Environment.NewLine
+ + " <html></html>" + Environment.NewLine
+ + "}",
+ new[] { SectionDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine + " "),
+ BlockFactory.MarkupTagBlock("<html>"),
+ BlockFactory.MarkupTagBlock("</html>"),
+ Factory.Markup(Environment.NewLine)),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseDocumentParsesWholeContentAsOneSpanIfNoSwapCharacterEncountered()
+ {
+ SingleSpanDocumentTest("foo baz", BlockKindInternal.Markup, SpanKindInternal.Markup);
+ }
+
+ [Fact]
+ public void ParseDocumentHandsParsingOverToCodeParserWhenAtSignEncounteredAndEmitsOutput()
+ {
+ ParseDocumentTest("foo @bar baz",
+ new MarkupBlock(
+ Factory.Markup("foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" baz")));
+ }
+
+ [Fact]
+ public void ParseDocumentEmitsAtSignAsMarkupIfAtEndOfFile()
+ {
+ ParseDocumentTest("foo @",
+ new MarkupBlock(
+ Factory.Markup("foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp()
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.EmptyHtml()),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndOfFileAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(5, 0, 5), contentLength: 1)));
+ }
+
+ [Fact]
+ public void ParseDocumentEmitsCodeBlockIfFirstCharacterIsSwapCharacter()
+ {
+ ParseDocumentTest("@bar",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotSwitchToCodeOnEmailAddressInText()
+ {
+ SingleSpanDocumentTest("anurse@microsoft.com", BlockKindInternal.Markup, SpanKindInternal.Markup);
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotSwitchToCodeOnEmailAddressInAttribute()
+ {
+ ParseDocumentTest("<a href=\"mailto:anurse@microsoft.com\">Email me</a>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href=\"", 2, 0, 2), new LocationTagged<string>("\"", 36, 0, 36)),
+ Factory.Markup(" href=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup("mailto:anurse@microsoft.com")
+ .With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), new LocationTagged<string>("mailto:anurse@microsoft.com", 9, 0, 9))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">")),
+ Factory.Markup("Email me"),
+ BlockFactory.MarkupTagBlock("</a>")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotReturnErrorOnMismatchedTags()
+ {
+ ParseDocumentTest("Foo <div><p></p></p> Baz",
+ new MarkupBlock(
+ Factory.Markup("Foo "),
+ BlockFactory.MarkupTagBlock("<div>"),
+ BlockFactory.MarkupTagBlock("<p>"),
+ BlockFactory.MarkupTagBlock("</p>"),
+ BlockFactory.MarkupTagBlock("</p>"),
+ Factory.Markup(" Baz")));
+ }
+
+ [Fact]
+ public void ParseDocumentReturnsOneMarkupSegmentIfNoCodeBlocksEncountered()
+ {
+ ParseDocumentTest("Foo Baz<!--Foo-->Bar<!--F> Qux",
+ new MarkupBlock(
+ Factory.Markup("Foo Baz"),
+ BlockFactory.HtmlCommentBlock("Foo"),
+ Factory.Markup("Bar"),
+ Factory.Markup("<!--F> Qux")));
+ }
+
+ [Fact]
+ public void ParseDocumentRendersTextPseudoTagAsMarkup()
+ {
+ ParseDocumentTest("Foo <text>Foo</text>",
+ new MarkupBlock(
+ Factory.Markup("Foo "),
+ BlockFactory.MarkupTagBlock("<text>"),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</text>")));
+ }
+
+ [Fact]
+ public void ParseDocumentAcceptsEndTagWithNoMatchingStartTag()
+ {
+ ParseDocumentTest("Foo </div> Bar",
+ new MarkupBlock(
+ Factory.Markup("Foo "),
+ BlockFactory.MarkupTagBlock("</div>"),
+ Factory.Markup(" Bar")));
+ }
+
+ [Fact]
+ public void ParseDocumentNoLongerSupportsDollarOpenBraceCombination()
+ {
+ ParseDocumentTest("<foo>${bar}</foo>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<foo>"),
+ Factory.Markup("${bar}"),
+ BlockFactory.MarkupTagBlock("</foo>")));
+ }
+
+ [Fact]
+ public void ParseDocumentIgnoresTagsInContentsOfScriptTag()
+ {
+ ParseDocumentTest(@"<script>foo<bar baz='@boz'></script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("foo<bar baz='"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'>"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotRenderExtraNewLineAtTheEndOfVerbatimBlock()
+ {
+ ParseDocumentTest("@{\r\n}\r\n<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("\r\n").With(SpanChunkGenerator.Null),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotRenderExtraWhitespaceAndNewLineAtTheEndOfVerbatimBlock()
+ {
+ ParseDocumentTest("@{\r\n} \t\r\n<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" \t\r\n").With(SpanChunkGenerator.Null),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotRenderExtraNewlineAtTheEndTextTagInVerbatimBlockIfFollowedByCSharp()
+ {
+ ParseDocumentTest("@{<text>Blah</text>\r\n\r\n}<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ Factory.Markup("Blah").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>"))),
+ Factory.Code("\r\n\r\n").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentRendersExtraNewlineAtTheEndTextTagInVerbatimBlockIfFollowedByHtml()
+ {
+ ParseDocumentTest("@{<text>Blah</text>\r\n<input/>\r\n}<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ Factory.Markup("Blah").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>")),
+ Factory.Markup("\r\n").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<input/>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("\r\n").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentRendersExtraNewlineAtTheEndTextTagInVerbatimBlockIfFollowedByMarkupTransition()
+ {
+ ParseDocumentTest("@{<text>Blah</text>\r\n@: Bleh\r\n}<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ Factory.Markup("Blah").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>")),
+ Factory.Markup("\r\n").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup(" Bleh\r\n")
+ .With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
+ .Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotIgnoreNewLineAtTheEndOfMarkupBlock()
+ {
+ ParseDocumentTest("@{\r\n}\r\n<html>\r\n",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("\r\n").With(SpanChunkGenerator.Null),
+ BlockFactory.MarkupTagBlock("<html>"),
+ Factory.Markup("\r\n")));
+ }
+
+ [Fact]
+ public void ParseDocumentDoesNotIgnoreWhitespaceAtTheEndOfVerbatimBlockIfNoNewlinePresent()
+ {
+ ParseDocumentTest("@{\r\n} \t<html>\r\n",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" \t"),
+ BlockFactory.MarkupTagBlock("<html>"),
+ Factory.Markup("\r\n")));
+ }
+
+ [Fact]
+ public void ParseDocumentHandlesNewLineInNestedBlock()
+ {
+ ParseDocumentTest("@{\r\n@if(true){\r\n} \r\n}\r\n<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true){\r\n}").AsStatement()),
+ Factory.Code(" \r\n").AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("\r\n").With(SpanChunkGenerator.Null),
+ BlockFactory.MarkupTagBlock("<html>")));
+ }
+
+ [Fact]
+ public void ParseDocumentHandlesNewLineAndMarkupInNestedBlock()
+ {
+ ParseDocumentTest("@{\r\n@if(true){\r\n} <input> }",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true){\r\n}").AsStatement()),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<input>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseDocumentHandlesExtraNewLineBeforeMarkupInNestedBlock()
+ {
+ ParseDocumentTest("@{\r\n@if(true){\r\n} \r\n<input> \r\n}<html>",
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ Factory.Code("\r\n").AsStatement().AutoCompleteWith(null, false),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code("if(true){\r\n}").AsStatement()),
+ Factory.Code(" \r\n").AsStatement(),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<input>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" \r\n").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<html>"))));
+ }
+
+ [Fact]
+ public void ParseSectionIgnoresTagsInContentsOfScriptTag()
+ {
+ ParseDocumentTest(
+ @"@section Foo { <script>foo<bar baz='@boz'></script> }",
+ new[] { SectionDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("foo<bar baz='"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup("'>"),
+ BlockFactory.MarkupTagBlock("</script>"),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void ParseBlockCanParse1000NestedElements()
+ {
+ var content = Nested1000.ReadAllText();
+ ParseDocument(content);
+ }
+
+ public static TheoryData BlockWithEscapedTransitionData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var datetimeBlock = new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace));
+
+ return new TheoryData<string, Block>
+ {
+ {
+ // Double transition in attribute value
+ "<span foo='@@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 13, 0, 13)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition at the end of attribute value
+ "<span foo='abc@@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 16, 0, 16)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("abc", 11, 0, 11))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 14, 0, 14), new LocationTagged<string>("@", 14, 0, 14))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition at the beginning of attribute value
+ "<span foo='@@def' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 16, 0, 16)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("def").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 13, 0, 13), new LocationTagged<string>("def", 13, 0, 13))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition in between attribute value
+ "<span foo='abc @@ def' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 21, 0, 21)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("abc", 11, 0, 11))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 14, 0, 14), new LocationTagged<string>("@", 15, 0, 15))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup(" def").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 17, 0, 17), new LocationTagged<string>("def", 18, 0, 18))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition with expression block
+ "<span foo='@@@DateTime.Now' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 26, 0, 26)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 13, 0, 13), 13, 0, 13),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ datetimeBlock),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<span foo='@DateTime.Now @@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 27, 0, 27)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), 11, 0, 11),
+ datetimeBlock),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 24, 0, 24), new LocationTagged<string>("@", 25, 0, 25))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<span foo='@(2+3)@@@DateTime.Now' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 32, 0, 32)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), 11, 0, 11),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("(").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None),
+ factory.Code("2+3").AsExpression(),
+ factory.MetaCode(")").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 17, 0, 17), new LocationTagged<string>("@", 17, 0, 17))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 19, 0, 19), 19, 0, 19),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ datetimeBlock),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<span foo='@@@(2+3)' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 19, 0, 19)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 13, 0, 13), 13, 0, 13),
+ factory.EmptyHtml().With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("(").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None),
+ factory.Code("2+3").AsExpression(),
+ factory.MetaCode(")").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<span foo='@DateTime.Now@@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 26, 0, 26)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), 11, 0, 11),
+ datetimeBlock),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 24, 0, 24), new LocationTagged<string>("@", 24, 0, 24))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition with email in attribute value
+ "<span foo='abc@def.com @@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 25, 0, 25)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc@def.com").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("abc@def.com", 11, 0, 11))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 22, 0, 22), new LocationTagged<string>("@", 23, 0, 23))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<span foo='abc@@def.com @@' />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 26, 0, 26)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ factory.Markup("abc").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("abc", 11, 0, 11))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 14, 0, 14), new LocationTagged<string>("@", 14, 0, 14))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("def.com").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 16, 0, 16), new LocationTagged<string>("def.com", 16, 0, 16))),
+ new MarkupBlock(
+ factory.Markup(" @").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(" ", 23, 0, 23), new LocationTagged<string>("@", 24, 0, 24))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ // Double transition before end of file
+ "<span foo='@@",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>(string.Empty, 13, 0, 13)),
+ factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>("@", 11, 0, 11))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)))),
+ factory.EmptyHtml())
+ },
+ {
+ // Double transition in complex regex in attribute value
+ @"<span foo=""/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@@[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i"" />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo=\"", 5, 0, 5), new LocationTagged<string>("\"", 111, 0, 111)),
+ factory.Markup(" foo=\"").With(SpanChunkGenerator.Null),
+ factory.Markup(@"/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), new LocationTagged<string>(@"/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+", 11, 0, 11))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 43, 0, 43), new LocationTagged<string>("@", 43, 0, 43))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup(@"[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 45, 0, 45), new LocationTagged<string>(@"[a-z0-9]([a-z0-9-]*[a-z0-9])?\.([a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i", 45, 0, 45))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(BlockWithEscapedTransitionData))]
+ public void ParseBlock_WithDoubleTransition_DoesNotThrow(string input, object expected)
+ {
+ FixupSpans = true;
+
+ // Act & Assert
+ ParseDocumentTest(input, (Block)expected);
+ }
+
+ [Fact]
+ public void ParseDocument_WithUnexpectedTransitionsInAttributeValue_Throws()
+ {
+ // Arrange
+ var expected = new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<span"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator("foo", new LocationTagged<string>(" foo='", 5, 0, 5), new LocationTagged<string>("'", 14, 0, 14)),
+ Factory.Markup(" foo='").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 11, 0, 11), 11, 0, 11),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.EmptyCSharp().AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(" ", 12, 0, 12), 12, 0, 12),
+ Factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ Factory.CodeTransition().Accepts(AcceptedCharactersInternal.None).With(SpanChunkGenerator.Null),
+ Factory.EmptyCSharp().AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("'").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />")));
+ var expectedErrors = new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedWhiteSpaceAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(12, 0, 12), contentLength: 1)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedCharacterAtStartOfCodeBlock(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 4),
+ "' />"),
+ };
+
+ // Act & Assert
+ ParseDocumentTest("<span foo='@ @' />", expected, expectedErrors);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlErrorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlErrorTest.cs
new file mode 100644
index 0000000000..497fceedaa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlErrorTest.cs
@@ -0,0 +1,110 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlErrorTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void ParseBlockAllowsInvalidTagNamesAsLongAsParserCanIdentifyEndTag()
+ {
+ ParseBlockTest("<1-foo+bar>foo</1-foo+bar>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<1-foo+bar>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("foo"),
+ new MarkupTagBlock(
+ Factory.Markup("</1-foo+bar>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockThrowsErrorIfStartTextTagContainsTextAfterName()
+ {
+ ParseBlockTest("<text foo bar></text>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text foo bar>").Accepts(AcceptedCharactersInternal.Any)),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>"))),
+ RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 4)));
+ }
+
+ [Fact]
+ public void ParseBlockThrowsErrorIfEndTextTagContainsTextAfterName()
+ {
+ ParseBlockTest("<text></text foo bar>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text foo bar>").Accepts(AcceptedCharactersInternal.Any))),
+ RazorDiagnosticFactory.CreateParsing_TextTagCannotContainAttributes(
+ new SourceSpan(new SourceLocation(8, 0, 8), contentLength: 4)));
+ }
+
+ [Fact]
+ public void ParseBlockThrowsExceptionIfBlockDoesNotStartWithTag()
+ {
+ ParseBlockTest("foo bar <baz>",
+ new MarkupBlock(),
+ RazorDiagnosticFactory.CreateParsing_MarkupBlockMustStartWithTag(
+ new SourceSpan(SourceLocation.Zero, contentLength: 3)));
+ }
+
+ [Fact]
+ public void ParseBlockStartingWithEndTagProducesRazorErrorThenOutputsMarkupSegmentAndEndsBlock()
+ {
+ ParseBlockTest("</foo> bar baz",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(new SourceLocation(2, 0, 2), contentLength: 3), "foo"));
+ }
+
+ [Fact]
+ public void ParseBlockWithUnclosedTopLevelTagThrowsMissingEndTagParserExceptionOnOutermostUnclosedTag()
+ {
+ ParseBlockTest("<p><foo></bar>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None))),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"));
+ }
+
+ [Fact]
+ public void ParseBlockWithUnclosedTagAtEOFThrowsMissingEndTagException()
+ {
+ ParseBlockTest("<foo>blah blah blah blah blah",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("blah blah blah blah blah")),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
+ }
+
+ [Fact]
+ public void ParseBlockWithUnfinishedTagAtEOFThrowsIncompleteTagException()
+ {
+ ParseBlockTest("<foo bar=baz",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("bar", new LocationTagged<string>(" bar=", 4, 0, 4), new LocationTagged<string>(string.Empty, 12, 0, 12)),
+ Factory.Markup(" bar=").With(SpanChunkGenerator.Null),
+ Factory.Markup("baz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), new LocationTagged<string>("baz", 9, 0, 9)))))),
+ RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlMarkupParserTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlMarkupParserTests.cs
new file mode 100644
index 0000000000..cc12a33914
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlMarkupParserTests.cs
@@ -0,0 +1,226 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test.Legacy
+{
+ public class HtmlMarkupParserTests
+ {
+ private static readonly HtmlSymbol doubleHyphenSymbol = new HtmlSymbol("--", HtmlSymbolType.DoubleHyphen);
+
+ public static IEnumerable<object[]> NonDashSymbols
+ {
+ get
+ {
+ yield return new[] { new HtmlSymbol("--", HtmlSymbolType.DoubleHyphen) };
+ yield return new[] { new HtmlSymbol("asdf", HtmlSymbolType.Text) };
+ yield return new[] { new HtmlSymbol(">", HtmlSymbolType.CloseAngle) };
+ yield return new[] { new HtmlSymbol("<", HtmlSymbolType.OpenAngle) };
+ yield return new[] { new HtmlSymbol("!", HtmlSymbolType.Bang) };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NonDashSymbols))]
+ public void IsHyphen_ReturnsFalseForNonDashSymbol(object symbol)
+ {
+ // Arrange
+ var convertedSymbol = (HtmlSymbol)symbol;
+
+ // Act & Assert
+ Assert.False(HtmlMarkupParser.IsHyphen(convertedSymbol));
+ }
+
+ [Fact]
+ public void IsHyphen_ReturnsTrueForADashSymbol()
+ {
+ // Arrange
+ var dashSymbol = new HtmlSymbol("-", HtmlSymbolType.Text);
+
+ // Act & Assert
+ Assert.True(HtmlMarkupParser.IsHyphen(dashSymbol));
+ }
+
+ [Fact]
+ public void AcceptAllButLastDoubleHypens_ReturnsTheOnlyDoubleHyphenSymbol()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-->");
+
+ // Act
+ var symbol = sut.AcceptAllButLastDoubleHyphens();
+
+ // Assert
+ Assert.Equal(doubleHyphenSymbol, symbol);
+ Assert.True(sut.At(HtmlSymbolType.CloseAngle));
+ Assert.Equal(doubleHyphenSymbol, sut.PreviousSymbol);
+ }
+
+ [Fact]
+ public void AcceptAllButLastDoubleHypens_ReturnsTheDoubleHyphenSymbolAfterAcceptingTheDash()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("--->");
+
+ // Act
+ var symbol = sut.AcceptAllButLastDoubleHyphens();
+
+ // Assert
+ Assert.Equal(doubleHyphenSymbol, symbol);
+ Assert.True(sut.At(HtmlSymbolType.CloseAngle));
+ Assert.True(HtmlMarkupParser.IsHyphen(sut.PreviousSymbol));
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsTrueForEmptyCommentTag()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("---->");
+
+ // Act & Assert
+ Assert.True(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTag()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- Some comment content in here -->");
+
+ // Act & Assert
+ Assert.True(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraDashesAtClosingTag()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- Some comment content in here ----->");
+
+ // Act & Assert
+ Assert.True(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsFalseForContentWithBadEndingAndExtraDash()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- Some comment content in here <!--->");
+
+ // Act & Assert
+ Assert.False(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsTrueForValidCommentTagWithExtraInfoAfter()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- comment --> the first part is a valid comment without the Open angle and bang symbols");
+
+ // Act & Assert
+ Assert.True(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsFalseForNotClosedComment()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- not closed comment");
+
+ // Act & Assert
+ Assert.False(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsFalseForCommentWithoutLastClosingAngle()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- not closed comment--");
+
+ // Act & Assert
+ Assert.False(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsHtmlCommentAhead_ReturnsTrueForCommentWithCodeInside()
+ {
+ // Arrange
+ var sut = CreateTestParserForContent("-- not closed @DateTime.Now comment-->");
+
+ // Act & Assert
+ Assert.True(sut.IsHtmlCommentAhead());
+ }
+
+ [Fact]
+ public void IsCommentContentEndingInvalid_ReturnsFalseForAllowedContent()
+ {
+ // Arrange
+ var expectedSymbol1 = new HtmlSymbol("a", HtmlSymbolType.Text);
+ var sequence = Enumerable.Range((int)'a', 26).Select(item => new HtmlSymbol(((char)item).ToString(), HtmlSymbolType.Text));
+
+ // Act & Assert
+ Assert.False(HtmlMarkupParser.IsCommentContentEndingInvalid(sequence));
+ }
+
+ [Fact]
+ public void IsCommentContentEndingInvalid_ReturnsTrueForDisallowedContent()
+ {
+ // Arrange
+ var expectedSymbol1 = new HtmlSymbol("a", HtmlSymbolType.Text);
+ var sequence = new[] { new HtmlSymbol("<", HtmlSymbolType.OpenAngle), new HtmlSymbol("!", HtmlSymbolType.Bang), new HtmlSymbol("-", HtmlSymbolType.Text) };
+
+ // Act & Assert
+ Assert.True(HtmlMarkupParser.IsCommentContentEndingInvalid(sequence));
+ }
+
+ [Fact]
+ public void IsCommentContentEndingInvalid_ReturnsFalseForEmptyContent()
+ {
+ // Arrange
+ var expectedSymbol1 = new HtmlSymbol("a", HtmlSymbolType.Text);
+ var sequence = Array.Empty<HtmlSymbol>();
+
+ // Act & Assert
+ Assert.False(HtmlMarkupParser.IsCommentContentEndingInvalid(sequence));
+ }
+
+ private class TestHtmlMarkupParser : HtmlMarkupParser
+ {
+ public new HtmlSymbol PreviousSymbol
+ {
+ get => base.PreviousSymbol;
+ }
+
+ public new bool IsHtmlCommentAhead()
+ {
+ return base.IsHtmlCommentAhead();
+ }
+
+ public TestHtmlMarkupParser(ParserContext context) : base(context)
+ {
+ this.EnsureCurrent();
+ }
+
+ public new HtmlSymbol AcceptAllButLastDoubleHyphens()
+ {
+ return base.AcceptAllButLastDoubleHyphens();
+ }
+
+ public override void BuildSpan(SpanBuilder span, SourceLocation start, string content)
+ {
+ base.BuildSpan(span, start, content);
+ }
+ }
+
+ private static TestHtmlMarkupParser CreateTestParserForContent(string content)
+ {
+ var source = TestRazorSourceDocument.Create(content);
+ var options = RazorParserOptions.CreateDefault();
+ var context = new ParserContext(source, options);
+
+ return new TestHtmlMarkupParser(context);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlParserTestUtils.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlParserTestUtils.cs
new file mode 100644
index 0000000000..3aa1829169
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlParserTestUtils.cs
@@ -0,0 +1,43 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ internal class HtmlParserTestUtils
+ {
+ public static void RunSingleAtEscapeTest(Action<string, Block> testMethod, AcceptedCharactersInternal lastSpanAcceptedCharacters = AcceptedCharactersInternal.None)
+ {
+ var factory = new SpanFactory();
+ testMethod("<foo>@@bar</foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>").Accepts(lastSpanAcceptedCharacters)),
+ factory.Markup("@").Hidden(),
+ factory.Markup("@bar"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>").Accepts(lastSpanAcceptedCharacters))));
+ }
+
+ public static void RunMultiAtEscapeTest(Action<string, Block> testMethod, AcceptedCharactersInternal lastSpanAcceptedCharacters = AcceptedCharactersInternal.None)
+ {
+ var factory = new SpanFactory();
+ testMethod("<foo>@@@@@bar</foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>").Accepts(lastSpanAcceptedCharacters)),
+ factory.Markup("@").Hidden(),
+ factory.Markup("@"),
+ factory.Markup("@").Hidden(),
+ factory.Markup("@"),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ factory.Markup("</foo>").Accepts(lastSpanAcceptedCharacters))));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTagsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTagsTest.cs
new file mode 100644
index 0000000000..5f22a1bae7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTagsTest.cs
@@ -0,0 +1,206 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlTagsTest : CsHtmlMarkupParserTestBase
+ {
+ public static IEnumerable<object[]> VoidElementNames
+ {
+ get
+ {
+ yield return new[] { "area" };
+ yield return new[] { "base" };
+ yield return new[] { "br" };
+ yield return new[] { "col" };
+ yield return new[] { "command" };
+ yield return new[] { "embed" };
+ yield return new[] { "hr" };
+ yield return new[] { "img" };
+ yield return new[] { "input" };
+ yield return new[] { "keygen" };
+ yield return new[] { "link" };
+ yield return new[] { "meta" };
+ yield return new[] { "param" };
+ yield return new[] { "source" };
+ yield return new[] { "track" };
+ yield return new[] { "wbr" };
+ }
+ }
+
+ [Fact]
+ public void EmptyTagNestsLikeNormalTag()
+ {
+ ParseBlockTest("<p></> Bar",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ BlockFactory.MarkupTagBlock("</>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"));
+ }
+
+ [Fact]
+ public void EmptyTag()
+ {
+ // This can happen in situations where a user is in VS' HTML editor and they're modifying
+ // the contents of an HTML tag.
+ ParseBlockTest("<></> Bar",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<>", AcceptedCharactersInternal.None),
+ BlockFactory.MarkupTagBlock("</>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void CommentTag()
+ {
+ ParseBlockTest("<!--Foo--> Bar",
+ new MarkupBlock(
+ BlockFactory.HtmlCommentBlock("Foo"),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void DocTypeTag()
+ {
+ ParseBlockTest("<!DOCTYPE html> foo",
+ new MarkupBlock(
+ Factory.Markup("<!DOCTYPE html>").Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ProcessingInstructionTag()
+ {
+ ParseBlockTest("<?xml version=\"1.0\" ?> foo",
+ new MarkupBlock(
+ Factory.Markup("<?xml version=\"1.0\" ?>").Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ElementTags()
+ {
+ ParseBlockTest("<p>Foo</p> Bar",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<p>", AcceptedCharactersInternal.None),
+ Factory.Markup("Foo"),
+ BlockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void TextTags()
+ {
+ ParseBlockTest("<text>Foo</text>}",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.MarkupTransition("<text>")),
+ Factory.Markup("Foo").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.MarkupTransition("</text>"))));
+ }
+
+ [Fact]
+ public void CDataTag()
+ {
+ ParseBlockTest("<![CDATA[Foo]]> Bar",
+ new MarkupBlock(
+ Factory.Markup("<![CDATA[Foo]]>").Accepts(AcceptedCharactersInternal.None),
+ Factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ScriptTag()
+ {
+ ParseDocumentTest("<script>foo < bar && quantity.toString() !== orderQty.val()</script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("foo < bar && quantity.toString() !== orderQty.val()"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Fact]
+ public void ScriptTag_WithNestedMalformedTag()
+ {
+ ParseDocumentTest("<script>var four = 4; /* </ */</script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("var four = 4; /* </ */"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Fact]
+ public void ScriptTag_WithNestedEndTag()
+ {
+ ParseDocumentTest("<script></p></script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("</p>"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Fact]
+ public void ScriptTag_WithNestedBeginTag()
+ {
+ ParseDocumentTest("<script><p></script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("<p>"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Fact]
+ public void ScriptTag_WithNestedTag()
+ {
+ ParseDocumentTest("<script><p></p></script>",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<script>"),
+ Factory.Markup("<p></p>"),
+ BlockFactory.MarkupTagBlock("</script>")));
+ }
+
+ [Theory]
+ [MemberData(nameof(VoidElementNames))]
+ public void VoidElementFollowedByContent(string tagName)
+ {
+ ParseBlockTest("<" + tagName + ">foo",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<" + tagName + ">", AcceptedCharactersInternal.None)));
+ }
+
+ [Theory]
+ [MemberData(nameof(VoidElementNames))]
+ public void VoidElementFollowedByOtherTag(string tagName)
+ {
+ ParseBlockTest("<" + tagName + "><other>foo",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<" + tagName + ">", AcceptedCharactersInternal.None)));
+ }
+
+ [Theory]
+ [MemberData(nameof(VoidElementNames))]
+ public void VoidElementFollowedByCloseTag(string tagName)
+ {
+ ParseBlockTest("<" + tagName + "> </" + tagName + ">foo",
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<" + tagName + ">", AcceptedCharactersInternal.None),
+ Factory.Markup(" "),
+ BlockFactory.MarkupTagBlock("</" + tagName + ">", AcceptedCharactersInternal.None)));
+ }
+
+ [Theory]
+ [MemberData(nameof(VoidElementNames))]
+ public void IncompleteVoidElementEndTag(string tagName)
+ {
+ ParseBlockTest("<" + tagName + "></" + tagName,
+ new MarkupBlock(
+ BlockFactory.MarkupTagBlock("<" + tagName + ">", AcceptedCharactersInternal.None),
+ BlockFactory.MarkupTagBlock("</" + tagName)));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs
new file mode 100644
index 0000000000..928762fbc6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs
@@ -0,0 +1,455 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlToCodeSwitchTest : CsHtmlMarkupParserTestBase
+ {
+ [Fact]
+ public void ParseBlockSwitchesWhenCharacterBeforeSwapIsNonAlphanumeric()
+ {
+ ParseBlockTest("<p>foo#@i</p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("foo#"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("i").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</p>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSwitchesToCodeWhenSwapCharacterEncounteredMidTag()
+ {
+ ParseBlockTest("<foo @bar />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSwitchesToCodeWhenSwapCharacterEncounteredInAttributeValue()
+ {
+ ParseBlockTest("<foo bar=\"@baz\" />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("bar", new LocationTagged<string>(" bar=\"", 4, 0, 4), new LocationTagged<string>("\"", 14, 0, 14)),
+ Factory.Markup(" bar=\"").With(SpanChunkGenerator.Null),
+ new MarkupBlock(new DynamicAttributeBlockChunkGenerator(new LocationTagged<string>(string.Empty, 10, 0, 10), 10, 0, 10),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("baz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSwitchesToCodeWhenSwapCharacterEncounteredInTagContent()
+ {
+ ParseBlockTest("<foo>@bar<baz>@boz</baz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("<baz>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml(),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("boz")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</baz>").Accepts(AcceptedCharactersInternal.None)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockParsesCodeWithinSingleLineMarkup()
+ {
+ // TODO: Fix at a later date, HTML should be a tag block: https://github.com/aspnet/Razor/issues/101
+ ParseBlockTest("@:<li>Foo @Bar Baz" + Environment.NewLine
+ + "bork",
+ new MarkupBlock(
+ Factory.MarkupTransition(),
+ Factory.MetaMarkup(":", HtmlSymbolType.Colon),
+ Factory.Markup("<li>Foo ").With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("Bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" Baz" + Environment.NewLine)
+ .Accepts(AcceptedCharactersInternal.None)));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCodeWithinComment()
+ {
+ ParseBlockTest("<foo><!-- @foo --></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ BlockFactory.HtmlCommentBlock(Factory, f => new SyntaxTreeNode[] {
+ f.Markup(" ").Accepts(AcceptedCharactersInternal.WhiteSpace),
+ new ExpressionBlock(
+ f.CodeTransition(),
+ f.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ f.Markup(" ").Accepts(AcceptedCharactersInternal.WhiteSpace) }),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCodeWithinSGMLDeclaration()
+ {
+ ParseBlockTest("<foo><!DOCTYPE foo @bar baz></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<!DOCTYPE foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" baz>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCodeWithinCDataDeclaration()
+ {
+ ParseBlockTest("<foo><![CDATA[ foo @bar baz]]></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<![CDATA[ foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" baz]]>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockSupportsCodeWithinXMLProcessingInstruction()
+ {
+ ParseBlockTest("<foo><?xml foo @bar baz?></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("<?xml foo "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ Factory.Markup(" baz?>").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotSwitchToCodeOnEmailAddressInText()
+ {
+ ParseBlockTest("<foo>anurse@microsoft.com</foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("anurse@microsoft.com"),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockDoesNotSwitchToCodeOnEmailAddressInAttribute()
+ {
+ ParseBlockTest("<a href=\"mailto:anurse@microsoft.com\">Email me</a>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<a"),
+ new MarkupBlock(new AttributeBlockChunkGenerator("href", new LocationTagged<string>(" href=\"", 2, 0, 2), new LocationTagged<string>("\"", 36, 0, 36)),
+ Factory.Markup(" href=\"").With(SpanChunkGenerator.Null),
+ Factory.Markup("mailto:anurse@microsoft.com")
+ .With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 9, 0, 9), new LocationTagged<string>("mailto:anurse@microsoft.com", 9, 0, 9))),
+ Factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Email me"),
+ new MarkupTagBlock(
+ Factory.Markup("</a>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseBlockGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
+ {
+ ParseBlockTest(" <ul>" + Environment.NewLine
+ + " @foreach(var p in Products) {" + Environment.NewLine
+ + " <li>Product: @p.Name</li>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " </ul>",
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<ul>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.Code(" ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code("foreach(var p in Products) {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Product: "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p.Name")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }" + Environment.NewLine).AsStatement().Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("</ul>").Accepts(AcceptedCharactersInternal.None))));
+ }
+
+ [Fact]
+ public void ParseDocumentGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
+ {
+ ParseDocumentTest(" <ul>" + Environment.NewLine
+ + " @foreach(var p in Products) {" + Environment.NewLine
+ + " <li>Product: @p.Name</li>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " </ul>",
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<ul>")),
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.Code(" ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code("foreach(var p in Products) {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Product: "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p.Name")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }" + Environment.NewLine).AsStatement().Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("</ul>"))));
+ }
+
+ [Fact]
+ public void SectionContextGivesWhitespacePreceedingAtToCodeIfThereIsNoMarkupOnThatLine()
+ {
+ var sectionDescriptor = SectionDirective.Directive;
+ ParseDocumentTest("@section foo {" + Environment.NewLine
+ + " <ul>" + Environment.NewLine
+ + " @foreach(var p in Products) {" + Environment.NewLine
+ + " <li>Product: @p.Name</li>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " </ul>" + Environment.NewLine
+ + "}",
+ new[] { SectionDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(Environment.NewLine + " "),
+ new MarkupTagBlock(
+ Factory.Markup("<ul>")),
+ Factory.Markup(Environment.NewLine),
+ new StatementBlock(
+ Factory.Code(" ").AsStatement(),
+ Factory.CodeTransition(),
+ Factory.Code("foreach(var p in Products) {" + Environment.NewLine).AsStatement(),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Product: "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p.Name")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
+ Factory.Code(" }" + Environment.NewLine).AsStatement().Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("</ul>")),
+ Factory.Markup(Environment.NewLine)),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void CSharpCodeParserDoesNotAcceptLeadingOrTrailingWhitespaceInDesignMode()
+ {
+ ParseBlockTest(" <ul>" + Environment.NewLine
+ + " @foreach(var p in Products) {" + Environment.NewLine
+ + " <li>Product: @p.Name</li>" + Environment.NewLine
+ + " }" + Environment.NewLine
+ + " </ul>",
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<ul>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine + " "),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.Code($"foreach(var p in Products) {{{Environment.NewLine} ").AsStatement(),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup("Product: "),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("p.Name").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</li>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.Code(Environment.NewLine + " }").AsStatement().Accepts(AcceptedCharactersInternal.None)),
+ Factory.Markup(Environment.NewLine + " "),
+ new MarkupTagBlock(
+ Factory.Markup("</ul>").Accepts(AcceptedCharactersInternal.None))),
+ designTime: true);
+ }
+
+ // Tests for "@@" escape sequence:
+ [Fact]
+ public void ParseBlockTreatsTwoAtSignsAsEscapeSequence()
+ {
+ HtmlParserTestUtils.RunSingleAtEscapeTest(ParseBlockTest);
+ }
+
+ [Fact]
+ public void ParseBlockTreatsPairsOfAtSignsAsEscapeSequence()
+ {
+ HtmlParserTestUtils.RunMultiAtEscapeTest(ParseBlockTest);
+ }
+
+ [Fact]
+ public void ParseDocumentTreatsTwoAtSignsAsEscapeSequence()
+ {
+ HtmlParserTestUtils.RunSingleAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharactersInternal.Any);
+ }
+
+ [Fact]
+ public void ParseDocumentTreatsPairsOfAtSignsAsEscapeSequence()
+ {
+ HtmlParserTestUtils.RunMultiAtEscapeTest(ParseDocumentTest, lastSpanAcceptedCharacters: AcceptedCharactersInternal.Any);
+ }
+
+ [Fact]
+ public void SectionBodyTreatsTwoAtSignsAsEscapeSequence()
+ {
+ ParseDocumentTest(
+ "@section Foo { <foo>@@bar</foo> }",
+ new[] { SectionDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<foo>")),
+ Factory.Markup("@").Hidden(),
+ Factory.Markup("@bar"),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+
+ [Fact]
+ public void SectionBodyTreatsPairsOfAtSignsAsEscapeSequence()
+ {
+ ParseDocumentTest(
+ "@section Foo { <foo>@@@@@bar</foo> }",
+ new[] { SectionDirective.Directive, },
+ new MarkupBlock(
+ Factory.EmptyHtml(),
+ new DirectiveBlock(new DirectiveChunkGenerator(SectionDirective.Directive),
+ Factory.CodeTransition(),
+ Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(SectionDirective.Directive.Tokens[0]),
+ Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace),
+ Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ Factory.Markup(" "),
+ new MarkupTagBlock(
+ Factory.Markup("<foo>")),
+ Factory.Markup("@").Hidden(),
+ Factory.Markup("@"),
+ Factory.Markup("@").Hidden(),
+ Factory.Markup("@"),
+ new ExpressionBlock(
+ Factory.CodeTransition(),
+ Factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ new MarkupTagBlock(
+ Factory.Markup("</foo>")),
+ Factory.Markup(" ")),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml()));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTest.cs
new file mode 100644
index 0000000000..529c2f9118
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTest.cs
@@ -0,0 +1,163 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class HtmlTokenizerTest : HtmlTokenizerTestBase
+ {
+ [Fact]
+ public void Next_Returns_Null_When_EOF_Reached()
+ {
+ TestTokenizer("");
+ }
+
+ [Fact]
+ public void Text_Is_Recognized()
+ {
+ TestTokenizer("foo-9309&smlkmb;::-3029022,.sdkq92384",
+ new HtmlSymbol("foo-9309&smlkmb;::-3029022,.sdkq92384", HtmlSymbolType.Text));
+ }
+
+ [Fact]
+ public void Whitespace_Is_Recognized()
+ {
+ TestTokenizer(" \t\f ",
+ new HtmlSymbol(" \t\f ", HtmlSymbolType.WhiteSpace));
+ }
+
+ [Fact]
+ public void Newline_Is_Recognized()
+ {
+ TestTokenizer("\n\r\r\n",
+ new HtmlSymbol("\n", HtmlSymbolType.NewLine),
+ new HtmlSymbol("\r", HtmlSymbolType.NewLine),
+ new HtmlSymbol("\r\n", HtmlSymbolType.NewLine));
+ }
+
+ [Fact]
+ public void Transition_Is_Not_Recognized_Mid_Text_If_Surrounded_By_Alphanumeric_Characters()
+ {
+ TestSingleToken("foo@bar", HtmlSymbolType.Text);
+ }
+
+ [Fact]
+ public void OpenAngle_Is_Recognized()
+ {
+ TestSingleToken("<", HtmlSymbolType.OpenAngle);
+ }
+
+ [Fact]
+ public void Bang_Is_Recognized()
+ {
+ TestSingleToken("!", HtmlSymbolType.Bang);
+ }
+
+ [Fact]
+ public void Solidus_Is_Recognized()
+ {
+ TestSingleToken("/", HtmlSymbolType.ForwardSlash);
+ }
+
+ [Fact]
+ public void QuestionMark_Is_Recognized()
+ {
+ TestSingleToken("?", HtmlSymbolType.QuestionMark);
+ }
+
+ [Fact]
+ public void LeftBracket_Is_Recognized()
+ {
+ TestSingleToken("[", HtmlSymbolType.LeftBracket);
+ }
+
+ [Fact]
+ public void CloseAngle_Is_Recognized()
+ {
+ TestSingleToken(">", HtmlSymbolType.CloseAngle);
+ }
+
+ [Fact]
+ public void RightBracket_Is_Recognized()
+ {
+ TestSingleToken("]", HtmlSymbolType.RightBracket);
+ }
+
+ [Fact]
+ public void Equals_Is_Recognized()
+ {
+ TestSingleToken("=", HtmlSymbolType.Equals);
+ }
+
+ [Fact]
+ public void DoubleQuote_Is_Recognized()
+ {
+ TestSingleToken("\"", HtmlSymbolType.DoubleQuote);
+ }
+
+ [Fact]
+ public void SingleQuote_Is_Recognized()
+ {
+ TestSingleToken("'", HtmlSymbolType.SingleQuote);
+ }
+
+ [Fact]
+ public void Transition_Is_Recognized()
+ {
+ TestSingleToken("@", HtmlSymbolType.Transition);
+ }
+
+ [Fact]
+ public void DoubleHyphen_Is_Recognized()
+ {
+ TestSingleToken("--", HtmlSymbolType.DoubleHyphen);
+ }
+
+ [Fact]
+ public void SingleHyphen_Is_Not_Recognized()
+ {
+ TestSingleToken("-", HtmlSymbolType.Text);
+ }
+
+ [Fact]
+ public void SingleHyphen_Mid_Text_Is_Not_Recognized_As_Separate_Token()
+ {
+ TestSingleToken("foo-bar", HtmlSymbolType.Text);
+ }
+
+ [Fact]
+ public void Next_Ignores_Star_At_EOF_In_RazorComment()
+ {
+ TestTokenizer(
+ "@* Foo * Bar * Baz *",
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol(" Foo * Bar * Baz *", HtmlSymbolType.RazorComment));
+ }
+
+ [Fact]
+ public void Next_Ignores_Star_Without_Trailing_At()
+ {
+ TestTokenizer(
+ "@* Foo * Bar * Baz *@",
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol(" Foo * Bar * Baz ", HtmlSymbolType.RazorComment),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition));
+ }
+
+ [Fact]
+ public void Next_Returns_RazorComment_Token_For_Entire_Razor_Comment()
+ {
+ TestTokenizer(
+ "@* Foo Bar Baz *@",
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol(" Foo Bar Baz ", HtmlSymbolType.RazorComment),
+ new HtmlSymbol("*", HtmlSymbolType.RazorCommentStar),
+ new HtmlSymbol("@", HtmlSymbolType.RazorCommentTransition));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTestBase.cs
new file mode 100644
index 0000000000..5e9a2d489e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlTokenizerTestBase.cs
@@ -0,0 +1,30 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class HtmlTokenizerTestBase : TokenizerTestBase
+ {
+ private static HtmlSymbol _ignoreRemaining = new HtmlSymbol(string.Empty, HtmlSymbolType.Unknown);
+
+ internal override object IgnoreRemaining
+ {
+ get { return _ignoreRemaining; }
+ }
+
+ internal override object CreateTokenizer(ITextDocument source)
+ {
+ return new HtmlTokenizer(source);
+ }
+
+ internal void TestSingleToken(string text, HtmlSymbolType expectedSymbolType)
+ {
+ TestTokenizer(text, new HtmlSymbol(text, expectedSymbolType));
+ }
+
+ internal void TestTokenizer(string input, params HtmlSymbol[] expectedSymbols)
+ {
+ base.TestTokenizer<HtmlSymbol, HtmlSymbolType>(input, expectedSymbols);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/LineTrackingStringBufferTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/LineTrackingStringBufferTest.cs
new file mode 100644
index 0000000000..27179a9f6d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/LineTrackingStringBufferTest.cs
@@ -0,0 +1,26 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class LineTrackingStringBufferTest
+ {
+ [Fact]
+ public void CtorInitializesProperties()
+ {
+ var buffer = new LineTrackingStringBuffer(string.Empty, "test.cshtml");
+ Assert.Equal(0, buffer.Length);
+ }
+
+ [Fact]
+ public void CharAtCorrectlyReturnsLocation()
+ {
+ var buffer = new LineTrackingStringBuffer("foo\rbar\nbaz\r\nbiz", "test.cshtml");
+ var chr = buffer.CharAt(14);
+ Assert.Equal('i', chr.Character);
+ Assert.Equal(new SourceLocation("test.cshtml", 14, 3, 1), chr.Location);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MarkupParserTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MarkupParserTestBase.cs
new file mode 100644
index 0000000000..16b1f43c1f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MarkupParserTestBase.cs
@@ -0,0 +1,25 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class MarkupParserTestBase : CodeParserTestBase
+ {
+ internal override RazorSyntaxTree ParseBlock(
+ RazorLanguageVersion version,
+ string document,
+ IEnumerable<DirectiveDescriptor> directives,
+ bool designTime)
+ {
+ return ParseHtmlBlock(version, document, directives, designTime);
+ }
+
+ internal virtual void SingleSpanDocumentTest(string document, BlockKindInternal blockKind, SpanKindInternal spanType)
+ {
+ var b = CreateSimpleBlockAndSpan(document, blockKind, spanType);
+ ParseDocumentTest(document, b);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MiscUtils.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MiscUtils.cs
new file mode 100644
index 0000000000..e014d24830
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/MiscUtils.cs
@@ -0,0 +1,33 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+#if DEBUG
+using System.Diagnostics;
+using System.Threading;
+#endif
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ class MiscUtils
+ {
+ public const int TimeoutInSeconds = 1;
+
+ public static void DoWithTimeoutIfNotDebugging(Func<int, bool> withTimeout)
+ {
+#if DEBUG
+ if (Debugger.IsAttached)
+ {
+ withTimeout(Timeout.Infinite);
+ }
+ else
+ {
+#endif
+ Assert.True(withTimeout((int)TimeSpan.FromSeconds(TimeoutInSeconds).TotalMilliseconds), "Timeout expired!");
+#if DEBUG
+ }
+#endif
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RazorParserTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RazorParserTest.cs
new file mode 100644
index 0000000000..589a147e4c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/RazorParserTest.cs
@@ -0,0 +1,86 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class RazorParserTest
+ {
+ [Fact]
+ public void CanParseStuff()
+ {
+ var parser = new RazorParser();
+ var sourceDocument = TestRazorSourceDocument.CreateResource("TestFiles/Source/BasicMarkup.cshtml", GetType());
+ var output = parser.Parse(sourceDocument);
+
+ Assert.NotNull(output);
+ }
+
+ [Fact]
+ public void ParseMethodCallsParseDocumentOnMarkupParserAndReturnsResults()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var parser = new RazorParser();
+
+ // Act/Assert
+ ParserTestBase.EvaluateResults(parser.Parse(TestRazorSourceDocument.Create("foo @bar baz")),
+ new MarkupBlock(
+ factory.Markup("foo "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" baz")));
+ }
+
+ [Fact]
+ public void ParseMethodUsesProvidedParserListenerIfSpecified()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var parser = new RazorParser();
+
+ // Act
+ var results = parser.Parse(TestRazorSourceDocument.Create("foo @bar baz"));
+
+ // Assert
+ ParserTestBase.EvaluateResults(results,
+ new MarkupBlock(
+ factory.Markup("foo "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("bar")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" baz")));
+ }
+
+ [Fact]
+ public void Parse_SyntaxTreeSpansAreLinked()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var parser = new RazorParser();
+
+ // Act
+ var results = parser.Parse(TestRazorSourceDocument.Create("foo @bar baz"));
+
+ // Assert
+ var spans = results.Root.Flatten().ToArray();
+ for (var i = 0; i < spans.Length - 1; i++)
+ {
+ Assert.Same(spans[i + 1], spans[i].Next);
+ }
+
+ for (var i = spans.Length - 1; i > 0; i--)
+ {
+ Assert.Same(spans[i - 1], spans[i].Previous);
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SourceLocationTrackerTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SourceLocationTrackerTest.cs
new file mode 100644
index 0000000000..9671ecedda
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SourceLocationTrackerTest.cs
@@ -0,0 +1,214 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class SourceLocationTrackerTest
+ {
+ private static readonly SourceLocation TestStartLocation = new SourceLocation(10, 42, 45);
+
+ [Fact]
+ public void ConstructorSetsCurrentLocationToZero()
+ {
+ Assert.Equal(SourceLocation.Zero, new SourceLocationTracker().CurrentLocation);
+ }
+
+ [Fact]
+ public void ConstructorWithSourceLocationSetsCurrentLocationToSpecifiedValue()
+ {
+ var loc = new SourceLocation(10, 42, 4);
+ Assert.Equal(loc, new SourceLocationTracker(loc).CurrentLocation);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("path-to-file")]
+ public void Advance_PreservesSourceLocationFilePath(string path)
+ {
+ // Arrange
+ var sourceLocation = new SourceLocation(path, 15, 2, 8);
+
+ // Act
+ var result = SourceLocationTracker.Advance(sourceLocation, "Hello world");
+
+ // Assert
+ Assert.Equal(path, result.FilePath);
+ Assert.Equal(26, result.AbsoluteIndex);
+ Assert.Equal(2, result.LineIndex);
+ Assert.Equal(19, result.CharacterIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesCorrectlyForMultiLineString()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation("foo\nbar\rbaz\r\nbox");
+
+ // Assert
+ Assert.Equal(26, tracker.CurrentLocation.AbsoluteIndex);
+ Assert.Equal(45, tracker.CurrentLocation.LineIndex);
+ Assert.Equal(3, tracker.CurrentLocation.CharacterIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesAbsoluteIndexOnNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('f', 'o');
+
+ // Assert
+ Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesCharacterIndexOnNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('f', 'o');
+
+ // Assert
+ Assert.Equal(46, tracker.CurrentLocation.CharacterIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationDoesNotAdvanceLineIndexOnNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('f', 'o');
+
+ // Assert
+ Assert.Equal(42, tracker.CurrentLocation.LineIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesLineIndexOnSlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\n', 'o');
+
+ // Assert
+ Assert.Equal(43, tracker.CurrentLocation.LineIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesAbsoluteIndexOnSlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\n', 'o');
+
+ // Assert
+ Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationResetsCharacterIndexOnSlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\n', 'o');
+
+ // Assert
+ Assert.Equal(0, tracker.CurrentLocation.CharacterIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesLineIndexOnSlashRFollowedByNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', 'o');
+
+ // Assert
+ Assert.Equal(43, tracker.CurrentLocation.LineIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesAbsoluteIndexOnSlashRFollowedByNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', 'o');
+
+ // Assert
+ Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationResetsCharacterIndexOnSlashRFollowedByNonNewlineCharacter()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', 'o');
+
+ // Assert
+ Assert.Equal(0, tracker.CurrentLocation.CharacterIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationDoesNotAdvanceLineIndexOnSlashRFollowedBySlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', '\n');
+
+ // Assert
+ Assert.Equal(42, tracker.CurrentLocation.LineIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesAbsoluteIndexOnSlashRFollowedBySlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', '\n');
+
+ // Assert
+ Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
+ }
+
+ [Fact]
+ public void UpdateLocationAdvancesCharacterIndexOnSlashRFollowedBySlashN()
+ {
+ // Arrange
+ var tracker = new SourceLocationTracker(TestStartLocation);
+
+ // Act
+ tracker.UpdateLocation('\r', '\n');
+
+ // Assert
+ Assert.Equal(46, tracker.CurrentLocation.CharacterIndex);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SpanTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SpanTest.cs
new file mode 100644
index 0000000000..5c52dd7967
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/SpanTest.cs
@@ -0,0 +1,78 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class SpanTest
+ {
+ [Fact]
+ public void ReplaceWith_ResetsLength()
+ {
+ // Arrange
+ var builder = new SpanBuilder(SourceLocation.Zero);
+ builder.Accept(new HtmlSymbol("hello", HtmlSymbolType.Text));
+ var span = builder.Build();
+ var newBuilder = new SpanBuilder(SourceLocation.Zero);
+ newBuilder.Accept(new HtmlSymbol("hi", HtmlSymbolType.Text));
+ var originalLength = span.Length;
+
+ // Act
+ span.ReplaceWith(newBuilder);
+
+ // Assert
+ Assert.Equal(5, originalLength);
+ Assert.Equal(2, span.Length);
+ }
+
+ // Note: This is more of an integration-like test. However, it's valuable to determine
+ // that the Span's ReplaceWith code is properly propogating change notifications to parents.
+ [Fact]
+ public void ReplaceWith_NotifiesParentChildHasChanged()
+ {
+ // Arrange
+ var spanBuilder = new SpanBuilder(SourceLocation.Zero);
+ spanBuilder.Accept(new HtmlSymbol("hello", HtmlSymbolType.Text));
+ var span = spanBuilder.Build();
+ var blockBuilder = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Markup,
+ };
+ blockBuilder.Children.Add(span);
+ var block = blockBuilder.Build();
+ span.Parent = block;
+ var originalBlockLength = block.Length;
+ var newSpanBuilder = new SpanBuilder(SourceLocation.Zero);
+ newSpanBuilder.Accept(new HtmlSymbol("hi", HtmlSymbolType.Text));
+
+ // Act
+ span.ReplaceWith(newSpanBuilder);
+
+ // Assert
+ Assert.Equal(5, originalBlockLength);
+ Assert.Equal(2, block.Length);
+ }
+
+ [Fact]
+ public void Clone_ClonesSpan()
+ {
+ // Arrange
+ var spanBuilder = new SpanBuilder(new SourceLocation(1, 2, 3))
+ {
+ EditHandler = new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString),
+ Kind = SpanKindInternal.Transition,
+ ChunkGenerator = new ExpressionChunkGenerator(),
+ };
+ spanBuilder.Accept(new CSharpSymbol("@", CSharpSymbolType.Transition));
+ var span = spanBuilder.Build();
+
+ // Act
+ var copy = (Span)span.Clone();
+
+ // Assert
+ Assert.Equal(span, copy);
+ Assert.NotSame(span, copy);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs
new file mode 100644
index 0000000000..06131ae599
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockRewriterTest.cs
@@ -0,0 +1,4014 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TagHelperBlockRewriterTest : TagHelperRewritingTestBase
+ {
+ public static TheoryData SymbolBoundAttributeData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<ul bound [item]='items'></ul>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("ul",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "[item]",
+ factory.CodeMarkup("items").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<ul bound [(item)]='items'></ul>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("ul",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "[(item)]",
+ factory.CodeMarkup("items").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<button bound (click)='doSomething()'>Click Me</button>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("button",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "(click)",
+ factory.CodeMarkup("doSomething()").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ },
+ children: factory.Markup("Click Me")))
+ },
+ {
+ "<button bound (^click)='doSomething()'>Click Me</button>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("button",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "(^click)",
+ factory.CodeMarkup("doSomething()").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ },
+ children: factory.Markup("Click Me")))
+ },
+ {
+ "<template bound *something='value'></template>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("template",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "*something",
+ factory.Markup("value"),
+ AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<div bound #localminimized></div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("#localminimized", null, AttributeStructure.Minimized)
+ }))
+ },
+ {
+ "<div bound #local='value'></div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("#local", factory.Markup("value"), AttributeStructure.SingleQuotes)
+ }))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(SymbolBoundAttributeData))]
+ public void Rewrite_CanHandleSymbolBoundAttributes(string documentContent, object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new[]
+ {
+ TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("*")
+ .RequireAttributeDescriptor(attribute => attribute.Name("bound")))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("[item]")
+ .PropertyName("ListItems")
+ .TypeName(typeof(List<string>).Namespace + "List<System.String>"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("[(item)]")
+ .PropertyName("ArrayItems")
+ .TypeName(typeof(string[]).Namespace + "System.String[]"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("(click)")
+ .PropertyName("Event1")
+ .TypeName(typeof(Action).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("(^click)")
+ .PropertyName("Event2")
+ .TypeName(typeof(Action).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("*something")
+ .PropertyName("StringProperty1")
+ .TypeName(typeof(string).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("#local")
+ .PropertyName("StringProperty2")
+ .TypeName(typeof(string).FullName))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData WithoutEndTagElementData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<input>",
+ new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
+ },
+ {
+ "<input type='text'>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagOnly,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("type", factory.Markup("text"), AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<input><input>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
+ },
+ {
+ "<input type='text'><input>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagOnly,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("type", factory.Markup("text"), AttributeStructure.SingleQuotes)
+ }),
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
+ },
+ {
+ "<div><input><input></div>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<div>"),
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ blockFactory.MarkupTagBlock("</div>"))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(WithoutEndTagElementData))]
+ public void Rewrite_CanHandleWithoutEndTagTagStructure(string documentContent, object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData TagStructureCompatibilityData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, structure1, structure2, expectedOutput
+ return new TheoryData<string, TagStructure, TagStructure, MarkupBlock>
+ {
+ {
+ "<input></input>",
+ TagStructure.Unspecified,
+ TagStructure.Unspecified,
+ new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagAndEndTag))
+ },
+ {
+ "<input />",
+ TagStructure.Unspecified,
+ TagStructure.Unspecified,
+ new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
+ },
+ {
+ "<input type='text'>",
+ TagStructure.Unspecified,
+ TagStructure.WithoutEndTag,
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagOnly,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("type", factory.Markup("text"), AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<input><input>",
+ TagStructure.WithoutEndTag,
+ TagStructure.WithoutEndTag,
+ new MarkupBlock(
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly))
+ },
+ {
+ "<input type='text'></input>",
+ TagStructure.Unspecified,
+ TagStructure.NormalOrSelfClosing,
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("type", factory.Markup("text"), AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<input />",
+ TagStructure.Unspecified,
+ TagStructure.WithoutEndTag,
+ new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
+ },
+
+ {
+ "<input />",
+ TagStructure.NormalOrSelfClosing,
+ TagStructure.Unspecified,
+ new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.SelfClosing))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(TagStructureCompatibilityData))]
+ public void Rewrite_AllowsCompatibleTagStructures(
+ string documentContent,
+ TagStructure structure1,
+ TagStructure structure2,
+ object expectedOutput)
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(structure1))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("InputTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(structure2))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData MalformedTagHelperAttributeBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ Func<string, Block> createInvalidDoBlock = extraCode =>
+ {
+ return new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(10, 0, 10)),
+ new SourceLocation(10, 0, 10)),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.Code("do {" + extraCode).AsStatement())));
+ };
+
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<p class='",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ factory.Markup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.SingleQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p bar=\"false\"\" <strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bar", factory.Markup("false"))
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p bar='false <strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bar",
+ new MarkupBlock(factory.Markup("false"), factory.Markup(" <strong>")),
+ AttributeStructure.SingleQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p bar='false <strong'",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bar",
+ new MarkupBlock(
+ factory.Markup("false"),
+ factory.Markup(" <strong")),
+ AttributeStructure.SingleQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p bar=false'",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bar",
+ factory.Markup("false"),
+ AttributeStructure.NoQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperAttributeListMustBeWellFormed(
+ new SourceSpan(12, 0, 12, 1))
+ }
+ },
+ {
+ "<p bar=\"false'",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bar",
+ factory.Markup("false'"))
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p bar=\"false' ></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bar",
+ new MarkupBlock(
+ factory.Markup("false'"),
+ factory.Markup(" ></p>")))
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p foo bar<strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("foo", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bar", null, AttributeStructure.Minimized)
+ },
+ new MarkupTagHelperBlock("strong"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(11, 0, 11), contentLength: 6), "strong"),
+ }
+ },
+ {
+ "<p class=btn\" bar<strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.NoQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p class=btn\" bar=\"foo\"<strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.NoQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p class=\"btn bar=\"foo\"<strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ new MarkupBlock(factory.Markup("btn"), factory.Markup(" bar="))),
+ new TagHelperAttributeNode("foo", null, AttributeStructure.Minimized)
+ },
+ new MarkupTagHelperBlock("strong"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(24, 0, 24), contentLength: 6), "strong")
+ }
+ },
+ {
+ "<p class=\"btn bar=\"foo\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ new MarkupBlock(factory.Markup("btn"), factory.Markup(" bar="))),
+ new TagHelperAttributeNode("foo", null, AttributeStructure.Minimized),
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p @DateTime.Now class=\"btn\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 13), "p")
+ }
+ },
+ {
+ "<p @DateTime.Now=\"btn\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 13), "p")
+ }
+ },
+ {
+ "<p class=@DateTime.Now\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(9, 0, 9)),
+ new SourceLocation(9, 0, 9)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))),
+ AttributeStructure.DoubleQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p class=\"@do {",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ createInvalidDoBlock(string.Empty))
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(11, 0, 11), contentLength: 1), "do", "}", "{"),
+ }
+ },
+ {
+ "<p class=\"@do {\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", createInvalidDoBlock("\"></p>"))
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(11, 0, 11), contentLength: 1), "do", "}", "{"),
+ RazorDiagnosticFactory.CreateParsing_UnterminatedStringLiteral(
+ new SourceSpan(filePath: null, absoluteIndex: 15, lineIndex: 0, characterIndex: 15, length: 1))
+ }
+ },
+ {
+ "<p @do { someattribute=\"btn\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 30), "p"),
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "do", "}", "{"),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 31, lineIndex: 0, characterIndex: 31, length: 1), "p")
+ }
+ },
+ {
+ "<p class=some=thing attr=\"@value\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("some"), AttributeStructure.NoQuotes)
+ })),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperAttributeListMustBeWellFormed(new SourceSpan(13, 0, 13, 13))
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(MalformedTagHelperAttributeBlockData))]
+ public void Rewrite_CreatesErrorForMalformedTagHelpersWithAttributes(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+ public static TheoryData MalformedTagHelperBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p></p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(absoluteIndex: 5, lineIndex: 0, characterIndex: 5, length: 1), "p")
+ }
+ },
+ {
+ "<p><strong",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 6), "strong")
+ }
+ },
+ {
+ "<strong <p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong",
+ new MarkupTagHelperBlock("p"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(9, 0, 9), contentLength: 1), "p")
+ }
+ },
+ {
+ "<strong </strong",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(10, 0, 10), contentLength: 6), "strong")
+ }
+ },
+ {
+ "<<</strong> <<p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ blockFactory.MarkupTagBlock("<"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ factory.Markup(" "),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 1), "p")
+ }
+ },
+ {
+ "<<<strong>> <<>>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("> "),
+ blockFactory.MarkupTagBlock("<"),
+ blockFactory.MarkupTagBlock("<>"),
+ factory.Markup(">"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(3, 0, 3), contentLength: 6), "strong")
+ }
+ },
+ {
+ "<str<strong></p></strong>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<str"),
+ new MarkupTagHelperBlock("strong",
+ blockFactory.MarkupTagBlock("</p>"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(14, 0, 14), contentLength: 1), "p")
+ }
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(MalformedTagHelperBlockData))]
+ public void Rewrite_CreatesErrorForMalformedTagHelper(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+ public static TheoryData CodeTagHelperAttributesData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var dateTimeNow = new MarkupBlock(
+ factory.Markup(" "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)));
+
+ return new TheoryData<string, Block>
+ {
+ {
+ "<person age=\"12\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("age", factory.CodeMarkup("12").With(new ExpressionChunkGenerator()))
+ }))
+ },
+ {
+ "<person birthday=\"DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "birthday",
+ factory.CodeMarkup("DateTime.Now").With(new ExpressionChunkGenerator()))
+ }))
+ },
+ {
+ "<person age=\"@DateTime.Now.Year\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "age",
+ new MarkupBlock(
+ new MarkupBlock(
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory
+ .CSharpCodeMarkup("DateTime.Now.Year")
+ .With(new ExpressionChunkGenerator())))))
+ }))
+ },
+ {
+ "<person age=\" @DateTime.Now.Year\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "age",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory
+ .CSharpCodeMarkup("DateTime.Now.Year")
+ .With(new ExpressionChunkGenerator())))))
+ }))
+ },
+ {
+ "<person name=\"John\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("name", factory.Markup("John"))
+ }))
+ },
+ {
+ "<person name=\"Time: @DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "name",
+ new MarkupBlock(factory.Markup("Time:"), dateTimeNow))
+ }))
+ },
+ {
+ "<person age=\"1 + @value + 2\" birthday='(bool)@Bag[\"val\"] ? @@DateTime : @DateTime.Now'/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "age",
+ new MarkupBlock(
+ factory.CodeMarkup("1").With(new ExpressionChunkGenerator()),
+ factory.CodeMarkup(" +").With(new ExpressionChunkGenerator()),
+ new MarkupBlock(
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("value")
+ .With(new ExpressionChunkGenerator()))),
+ factory.CodeMarkup(" +").With(new ExpressionChunkGenerator()),
+ factory.CodeMarkup(" 2").With(new ExpressionChunkGenerator()))),
+ new TagHelperAttributeNode(
+ "birthday",
+ new MarkupBlock(
+ factory.CodeMarkup("(bool)").With(new ExpressionChunkGenerator()),
+ new MarkupBlock(
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory
+ .CSharpCodeMarkup("Bag[\"val\"]")
+ .With(new ExpressionChunkGenerator()))),
+ factory.CodeMarkup(" ?").With(new ExpressionChunkGenerator()),
+ new MarkupBlock(
+ factory.CodeMarkup(" @").With(new ExpressionChunkGenerator())
+ .As(SpanKindInternal.Code),
+ factory.CodeMarkup("@").With(SpanChunkGenerator.Null)
+ .As(SpanKindInternal.Code)),
+ factory.CodeMarkup("DateTime").With(new ExpressionChunkGenerator()),
+ factory.CodeMarkup(" :").With(new ExpressionChunkGenerator()),
+ new MarkupBlock(
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory
+ .CSharpCodeMarkup("DateTime.Now")
+ .With(new ExpressionChunkGenerator())))),
+ AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("age", factory.CodeMarkup("12").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "birthday",
+ factory.CodeMarkup("DateTime.Now").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "name",
+ new MarkupBlock(factory.Markup("Time:"), dateTimeNow))
+ }))
+ },
+ {
+ "<person age=\"12\" birthday=\"DateTime.Now\" name=\"Time: @@ @DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("age", factory.CodeMarkup("12").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "birthday",
+ factory.CodeMarkup("DateTime.Now").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "name",
+ new MarkupBlock(
+ factory.Markup("Time:"),
+ new MarkupBlock(
+ factory.Markup(" @").Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@")
+ .With(SpanChunkGenerator.Null)
+ .Accepts(AcceptedCharactersInternal.None)),
+ dateTimeNow))
+ }))
+ },
+ {
+ "<person age=\"12\" birthday=\"DateTime.Now\" name=\"@@BoundStringAttribute\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("age", factory.CodeMarkup("12").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "birthday",
+ factory.CodeMarkup("DateTime.Now").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "name",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.Markup("@").Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@")
+ .With(SpanChunkGenerator.Null)
+ .Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("BoundStringAttribute")))
+ }))
+ },
+ {
+ "<person age=\"@@@(11+1)\" birthday=\"DateTime.Now\" name=\"Time: @DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("person",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "age",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.CodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory.CodeMarkup("@").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ factory.EmptyHtml()
+ .AsCodeMarkup().With(new ExpressionChunkGenerator())
+ .As(SpanKindInternal.Code),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("(").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("11+1")
+ .With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup(")").With(new ExpressionChunkGenerator()))))),
+ new TagHelperAttributeNode(
+ "birthday",
+ factory.CodeMarkup("DateTime.Now").With(new ExpressionChunkGenerator())),
+ new TagHelperAttributeNode(
+ "name",
+ new MarkupBlock(factory.Markup("Time:"), dateTimeNow))
+ }))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(CodeTagHelperAttributesData))]
+ public void Rewrite_CreatesMarkupCodeSpansForNonStringTagHelperAttributes(
+ string documentContent,
+ object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PersonTagHelper", "personAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("person"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("age")
+ .PropertyName("Age")
+ .TypeName(typeof(int).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("birthday")
+ .PropertyName("BirthDay")
+ .TypeName(typeof(DateTime).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("name")
+ .PropertyName("Name")
+ .TypeName(typeof(string).FullName))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ documentContent,
+ (MarkupBlock)expectedOutput,
+ expectedErrors: Enumerable.Empty<RazorDiagnostic>());
+ }
+
+ public static IEnumerable<object[]> IncompleteHelperBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now style=color:red;><strong></p></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode(
+ "dynamic",
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(21, 0, 21)),
+ new SourceLocation(21, 0, 21)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), AttributeStructure.NoQuotes)
+ },
+ new MarkupTagHelperBlock("strong")),
+ blockFactory.MarkupTagBlock("</strong>")),
+ new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 53, lineIndex: 0, characterIndex: 53, length: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 66, lineIndex: 0, characterIndex: 66, length: 6), "strong")
+ }
+ };
+ yield return new object[]
+ {
+ "<div><p>Hello <strong>World</strong></div>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<div>"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("World")),
+ blockFactory.MarkupTagBlock("</div>"))),
+ new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 6, lineIndex: 0, characterIndex: 6, length: 1), "p")
+ }
+ };
+ yield return new object[]
+ {
+ "<div><p>Hello <strong>World</div>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<div>"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("World"),
+ blockFactory.MarkupTagBlock("</div>")))),
+ new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 6, lineIndex: 0, characterIndex: 6, length: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 15, lineIndex: 0, characterIndex: 15, length: 6), "strong")
+ }
+ };
+ yield return new object[]
+ {
+ "<p class=\"foo\">Hello <p style=\"color:red;\">World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"))
+ },
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ },
+ factory.Markup("World")))),
+ new RazorDiagnostic[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(IncompleteHelperBlockData))]
+ public void TagHelperParseTreeRewriter_CreatesErrorForIncompleteTagHelper(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+
+ public static IEnumerable<object[]> OddlySpacedBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ yield return new object[]
+ {
+ "<p class=\" foo\" style=\" color : red ; \" ></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup(" foo")),
+ new TagHelperAttributeNode(
+ "style",
+ new MarkupBlock(
+ factory.Markup(" color"),
+ factory.Markup(" :"),
+ factory.Markup(" red"),
+ factory.Markup(" ;"),
+ factory.Markup(" ")))
+ }))
+ };
+ yield return new object[]
+ {
+ "<p class=\" foo\" style=\" color : red ; \" >Hello World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup(" foo")),
+ new TagHelperAttributeNode(
+ "style",
+ new MarkupBlock(
+ factory.Markup(" color"),
+ factory.Markup(" :"),
+ factory.Markup(" red"),
+ factory.Markup(" ;"),
+ factory.Markup(" ")))
+ },
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "<p class=\" foo \" >Hello</p> <p style=\" color:red; \" >World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ new MarkupBlock(factory.Markup(" foo"), factory.Markup(" ")))
+ },
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "style",
+ new MarkupBlock(factory.Markup(" color:red;"), factory.Markup(" ")))
+ },
+ factory.Markup("World")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OddlySpacedBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesOddlySpacedTagHelperTagBlocks(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static IEnumerable<object[]> ComplexAttributeTagHelperBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNowString = "@DateTime.Now";
+ var dateTimeNow = new Func<int, SyntaxTreeNode>(index =>
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(index, 0, index)),
+ new SourceLocation(index, 0, index)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))));
+ var doWhileString = "@do { var foo = bar; <text>Foo</text> foo++; } while (foo<bar>);";
+ var doWhile = new Func<int, SyntaxTreeNode>(index =>
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(index, 0, index)),
+ new SourceLocation(index, 0, index)),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.Code("do { var foo = bar; ").AsStatement(),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.MarkupTransition("<text>")),
+ factory.Markup("Foo").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ factory.MarkupTransition("</text>"))),
+ factory
+ .Code(" foo++; } while (foo<bar>);")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None)))));
+
+ var currentFormattedString = "<p class=\"{0}\" style='{0}'></p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10)),
+ new TagHelperAttributeNode("style", dateTimeNow(32), AttributeStructure.SingleQuotes)
+ }))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", doWhile(10)),
+ new TagHelperAttributeNode("style", doWhile(83), AttributeStructure.SingleQuotes)
+ }))
+ };
+
+ currentFormattedString = "<p class=\"{0}\" style='{0}'>Hello World</p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10)),
+ new TagHelperAttributeNode("style", dateTimeNow(32), AttributeStructure.SingleQuotes)
+ },
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", doWhile(10)),
+ new TagHelperAttributeNode("style", doWhile(83), AttributeStructure.SingleQuotes)
+ },
+ factory.Markup("Hello World")))
+ };
+
+ currentFormattedString = "<p class=\"{0}\">Hello</p> <p style='{0}'>World</p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10))
+ },
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", dateTimeNow(45), AttributeStructure.SingleQuotes)
+ },
+ factory.Markup("World")))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", doWhile(10))
+ },
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", doWhile(96), AttributeStructure.SingleQuotes)
+ },
+ factory.Markup("World")))
+ };
+
+ currentFormattedString =
+ "<p class=\"{0}\" style='{0}'>Hello World <strong class=\"{0}\">inside of strong tag</strong></p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10)),
+ new TagHelperAttributeNode("style", dateTimeNow(32), AttributeStructure.SingleQuotes)
+ },
+ factory.Markup("Hello World "),
+ new MarkupTagBlock(
+ factory.Markup("<strong"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 66, 0, 66),
+ suffix: new LocationTagged<string>("\"", 87, 0, 87)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(string.Empty, 74, 0, 74), 74, 0, 74),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("inside of strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ComplexAttributeTagHelperBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesComplexAttributeTagHelperTagBlocks(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static IEnumerable<object[]> ComplexTagHelperBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNowString = "@DateTime.Now";
+ var dateTimeNow = new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace));
+ var doWhileString = "@do { var foo = bar; <p>Foo</p> foo++; } while (foo<bar>);";
+ var doWhile = new StatementBlock(
+ factory.CodeTransition(),
+ factory.Code("do { var foo = bar;").AsStatement(),
+ new MarkupBlock(
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Foo")),
+ factory.Markup(" ").Accepts(AcceptedCharactersInternal.None)),
+ factory.Code("foo++; } while (foo<bar>);")
+ .AsStatement()
+ .Accepts(AcceptedCharactersInternal.None));
+
+ var currentFormattedString = "<p>{0}</p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p", dateTimeNow))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p", doWhile))
+ };
+
+ currentFormattedString = "<p>Hello World {0}</p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World "),
+ dateTimeNow))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World "),
+ doWhile))
+ };
+
+ currentFormattedString = "<p>{0}</p> <p>{0}</p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p", dateTimeNow),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p", dateTimeNow))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p", doWhile),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p", doWhile))
+ };
+
+ currentFormattedString = "<p>Hello {0}<strong>inside of {0} strong tag</strong></p>";
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, dateTimeNowString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ dateTimeNow,
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("inside of "),
+ dateTimeNow,
+ factory.Markup(" strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ yield return new object[]
+ {
+ string.Format(currentFormattedString, doWhileString),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ doWhile,
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("inside of "),
+ doWhile,
+ factory.Markup(" strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ComplexTagHelperBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesComplexTagHelperTagBlocks(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+
+ public static TheoryData InvalidHtmlBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNow = new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace));
+
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<<<p>>></p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup(">>")))
+ },
+ {
+ "<<p />",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p", TagMode.SelfClosing))
+ },
+ {
+ "< p />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ new MarkupBlock(
+ factory.Markup(" p")),
+ factory.Markup(" />")))
+ },
+ {
+ "<input <p />",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<input "),
+ new MarkupTagHelperBlock("p", TagMode.SelfClosing))
+ },
+ {
+ "< class=\"foo\" <p />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 1, 0, 1),
+ suffix: new LocationTagged<string>("\"", 12, 0, 12)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("foo").With(new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 9, 0, 9),
+ value: new LocationTagged<string>("foo", 9, 0, 9))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" ")),
+ new MarkupTagHelperBlock("p", TagMode.SelfClosing))
+ },
+ {
+ "</<<p>/></p>>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</"),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("/>")),
+ factory.Markup(">"))
+ },
+ {
+ "</<<p>/><strong></p>>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</"),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("/>"),
+ blockFactory.MarkupTagBlock("<strong>")),
+ factory.Markup(">"))
+ },
+ {
+ "</<<p>@DateTime.Now/><strong></p>>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</"),
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ dateTimeNow,
+ factory.Markup("/>"),
+ blockFactory.MarkupTagBlock("<strong>")),
+ factory.Markup(">"))
+ },
+ {
+ "</ /< ><p>@DateTime.Now / ><strong></p></ >",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</ "),
+ factory.Markup("/"),
+ blockFactory.MarkupTagBlock("< >"),
+ new MarkupTagHelperBlock("p",
+ dateTimeNow,
+ factory.Markup(" / >"),
+ blockFactory.MarkupTagBlock("<strong>")),
+ blockFactory.MarkupTagBlock("</ >"))
+ },
+ {
+ "<p>< @DateTime.Now ></ @DateTime.Now ></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagBlock(
+ factory.Markup("< "),
+ dateTimeNow,
+ factory.Markup(" >")),
+ blockFactory.MarkupTagBlock("</ "),
+ dateTimeNow,
+ factory.Markup(" >")))
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(InvalidHtmlBlockData))]
+ public void TagHelperParseTreeRewriter_AllowsInvalidHtml(string documentContent, object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static TheoryData EmptyAttributeTagHelperData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<p class=\"\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", new MarkupBlock())
+ }))
+ },
+ {
+ "<p class=''></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", new MarkupBlock(), AttributeStructure.SingleQuotes)
+ }))
+ },
+ {
+ "<p class=></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ // We expected a markup node here because attribute values without quotes can only ever
+ // be a single item, hence don't need to be enclosed by a block.
+ new TagHelperAttributeNode(
+ "class",
+ factory.Markup("").With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ }))
+ },
+ {
+ "<p class1='' class2= class3=\"\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class1", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode(
+ "class2",
+ factory.Markup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode("class3", new MarkupBlock()),
+ }))
+ },
+ {
+ "<p class1=''class2=\"\"class3= />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class1", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("class2", new MarkupBlock()),
+ new TagHelperAttributeNode(
+ "class3",
+ factory.Markup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ }))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(EmptyAttributeTagHelperData))]
+ public void Rewrite_UnderstandsEmptyAttributeTagHelpers(string documentContent, object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, new RazorDiagnostic[0], "p");
+ }
+
+ public static TheoryData EmptyTagHelperBoundAttributeData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var boolTypeName = typeof(bool).FullName;
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<myth bound='' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", new MarkupBlock(), AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName)
+ }
+ },
+ {
+ "<myth bound=' true' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(" true").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<myth bound=' ' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound='' bound=\"\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("bound", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound", new MarkupBlock())
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(16, 0, 16, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound=' ' bound=\" \" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(" "))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(17, 0, 17, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound='true' bound= />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup("true").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(19, 0, 19, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound= name='' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode("name", new MarkupBlock(), AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound= name=' ' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode("name", factory.Markup(" "), AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound='true' name='john' bound= name= />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup("true").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("name", factory.Markup("john"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode(
+ "bound",
+ factory.CodeMarkup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode(
+ "name",
+ factory.Markup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(31, 0, 31, 5),
+ "bound",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth BouND='' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("BouND", new MarkupBlock(), AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "BouND",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth BOUND='' bOUnd=\"\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("BOUND", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bOUnd", new MarkupBlock())
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "BOUND",
+ "myth",
+ boolTypeName),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(18, 0, 18, 5),
+ "bOUnd",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth BOUND= nAMe='john'></myth>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "BOUND",
+ factory.CodeMarkup(string.Empty).With(SpanChunkGenerator.Null),
+ AttributeStructure.DoubleQuotes),
+ new TagHelperAttributeNode("nAMe", factory.Markup("john"), AttributeStructure.SingleQuotes)
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 5),
+ "BOUND",
+ "myth",
+ boolTypeName),
+ }
+ },
+ {
+ "<myth bound=' @true ' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("true")
+ .With(new ExpressionChunkGenerator()))),
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator())),
+ AttributeStructure.SingleQuotes)
+ }
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<myth bound=' @(true) ' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "myth",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator()),
+ new ExpressionBlock(
+ factory.CSharpCodeMarkup("@").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("(").With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup("true")
+ .With(new ExpressionChunkGenerator()),
+ factory.CSharpCodeMarkup(")").With(new ExpressionChunkGenerator()))),
+ factory.CodeMarkup(" ").With(new ExpressionChunkGenerator())),
+ AttributeStructure.SingleQuotes)
+ }
+ })),
+ new RazorDiagnostic[0]
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(EmptyTagHelperBoundAttributeData))]
+ public void Rewrite_CreatesErrorForEmptyTagHelperBoundAttributes(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("mythTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("myth"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound")
+ .PropertyName("Bound")
+ .TypeName(typeof(bool).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("name")
+ .PropertyName("Name")
+ .TypeName(typeof(string).FullName))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors);
+ }
+
+ public static IEnumerable<object[]> ScriptBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ yield return new object[]
+ {
+ "<script><script></foo></script>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("script",
+ factory.Markup("<script></foo>")))
+ };
+ yield return new object[]
+ {
+ "<script>Hello World <div></div></script>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("script",
+ factory.Markup("Hello World <div></div>")))
+ };
+ yield return new object[]
+ {
+ "<script>Hel<p>lo</p></script> <p><div>World</div></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("script",
+ factory.Markup("Hel<p>lo</p>")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("div",
+ factory.Markup("World"))))
+ };
+ yield return new object[]
+ {
+ "<script>Hel<strong>lo</strong></script> <script><span>World</span></script>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("script",
+ factory.Markup("Hel<strong>lo</strong>")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("script",
+ factory.Markup("<span>World</span>")))
+ };
+ yield return new object[]
+ {
+ "<script class=\"foo\" style=\"color:red;\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("script",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }))
+ };
+ yield return new object[]
+ {
+ "<p>Hello <script class=\"foo\" style=\"color:red;\"></script> World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock("script",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }),
+ factory.Markup(" World")))
+ };
+ yield return new object[]
+ {
+ "<p>Hello <script class=\"@@foo@bar.com\" style=\"color:red;\"></script> World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock("script",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "class",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.Markup("@").Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("foo@bar.com"))),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }),
+ factory.Markup(" World")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(ScriptBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesScriptTagHelpers(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p", "div", "script");
+ }
+
+ public static IEnumerable<object[]> SelfClosingBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ yield return new object[]
+ {
+ "<p class=\"foo\" style=\"color:red;\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }))
+ };
+ yield return new object[]
+ {
+ "<p>Hello <p class=\"foo\" style=\"color:red;\" /> World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ children: new SyntaxTreeNode[]
+ {
+ factory.Markup("Hello "),
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode(
+ "style",
+ factory.Markup("color:red;"))
+ }),
+ factory.Markup(" World")
+ }))
+ };
+ yield return new object[]
+ {
+ "Hello<p class=\"foo\" /> <p style=\"color:red;\" />World",
+ new MarkupBlock(
+ factory.Markup("Hello"),
+ new MarkupTagHelperBlock("p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"))
+ }),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }),
+ factory.Markup("World"))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(SelfClosingBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesSelfClosingTagHelpers(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static IEnumerable<object[]> QuotelessAttributeBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNow = new Func<int, SyntaxTreeNode>(index =>
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(index, 0, index)),
+ new SourceLocation(index, 0, index)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))));
+
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now style=color:red;></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), AttributeStructure.NoQuotes)
+ }))
+ };
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now style=color:red;>Hello World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), AttributeStructure.NoQuotes)
+ },
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now style=color@@:red;>Hello World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
+ new TagHelperAttributeNode(
+ "style",
+ new MarkupBlock(
+ factory.Markup("color"),
+ new MarkupBlock(
+ factory.Markup("@").Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup(":red;")),
+ AttributeStructure.DoubleQuotes)
+ },
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now>Hello</p> <p style=color:red; dynamic=@DateTime.Now>World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(21))
+ },
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(73))
+ },
+ factory.Markup("World")))
+ };
+ yield return new object[]
+ {
+ "<p class=foo dynamic=@DateTime.Now style=color:red;>Hello World <strong class=\"foo\">inside of strong tag</strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("dynamic", dateTimeNow(21)),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"), AttributeStructure.NoQuotes)
+ },
+ factory.Markup("Hello World "),
+ new MarkupTagBlock(
+ factory.Markup("<strong"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 71, 0, 71),
+ suffix: new LocationTagged<string>("\"", 82, 0, 82)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 79, 0, 79),
+ value: new LocationTagged<string>("foo", 79, 0, 79))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("inside of strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(QuotelessAttributeBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesTagHelpersWithQuotelessAttributes(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static IEnumerable<object[]> PlainAttributeBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ yield return new object[]
+ {
+ "<p class=\"foo\" style=\"color:red;\"></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ }))
+ };
+ yield return new object[]
+ {
+ "<p class=\"foo\" style=\"color:red;\">Hello World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ },
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "<p class=\"foo\">Hello</p> <p style=\"color:red;\">World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo"))
+ },
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ },
+ factory.Markup("World")))
+ };
+ yield return new object[]
+ {
+ "<p class=\"foo\" style=\"color:red;\">Hello World <strong class=\"foo\">inside of strong tag</strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("foo")),
+ new TagHelperAttributeNode("style", factory.Markup("color:red;"))
+ },
+ factory.Markup("Hello World "),
+ new MarkupTagBlock(
+ factory.Markup("<strong"),
+ new MarkupBlock(new AttributeBlockChunkGenerator(name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 53, 0, 53),
+ suffix: new LocationTagged<string>("\"", 64, 0, 64)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("foo").With(new LiteralAttributeChunkGenerator(prefix: new LocationTagged<string>(string.Empty, 61, 0, 61),
+ value: new LocationTagged<string>("foo", 61, 0, 61))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("inside of strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(PlainAttributeBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesTagHelpersWithPlainAttributes(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static IEnumerable<object[]> PlainBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ yield return new object[]
+ {
+ "<p></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p"))
+ };
+ yield return new object[]
+ {
+ "<p>Hello World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "<p>Hello</p> <p>World</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("World")))
+ };
+ yield return new object[]
+ {
+ "<p>Hello World <strong>inside of strong tag</strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World "),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("inside of strong tag"),
+ blockFactory.MarkupTagBlock("</strong>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(PlainBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesPlainTagHelperTagBlocks(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p");
+ }
+
+ public static TheoryData DataDashAttributeData_Document
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var dateTimeNowString = "@DateTime.Now";
+ var dateTimeNow = new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace));
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ $"<input data-required='{dateTimeNowString}' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(dateTimeNow),
+ AttributeStructure.SingleQuotes),
+ }))
+ },
+ {
+ "<input data-required='value' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("data-required", factory.Markup("value"), AttributeStructure.SingleQuotes),
+ }))
+ },
+ {
+ $"<input data-required='prefix {dateTimeNowString}' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(factory.Markup("prefix "), dateTimeNow),
+ AttributeStructure.SingleQuotes),
+ }))
+ },
+ {
+ $"<input data-required='{dateTimeNowString} suffix' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(dateTimeNow, factory.Markup(" suffix")),
+ AttributeStructure.SingleQuotes),
+ }))
+ },
+ {
+ $"<input data-required='prefix {dateTimeNowString} suffix' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(
+ factory.Markup("prefix "),
+ dateTimeNow,
+ factory.Markup(" suffix")),
+ AttributeStructure.SingleQuotes),
+ }))
+ },
+ {
+ $"<input pre-attribute data-required='prefix {dateTimeNowString} suffix' post-attribute />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("pre-attribute", value: null, attributeStructure: AttributeStructure.Minimized),
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(
+ factory.Markup("prefix "),
+ dateTimeNow,
+ factory.Markup(" suffix")),
+ AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("post-attribute", value: null, attributeStructure: AttributeStructure.Minimized),
+ }))
+ },
+ {
+ $"<input data-required='{dateTimeNowString} middle {dateTimeNowString}' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode(
+ "data-required",
+ new MarkupBlock(
+ dateTimeNow,
+ factory.Markup(" middle "),
+ dateTimeNow),
+ AttributeStructure.SingleQuotes),
+ }))
+ },
+ };
+ }
+ }
+
+ public static TheoryData DataDashAttributeData_CSharpBlock
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var documentData = DataDashAttributeData_Document;
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+
+ foreach (var data in documentData)
+ {
+ data[0] = $"@{{{data[0]}}}";
+ data[1] = buildStatementBlock(() => data[1] as MarkupBlock);
+ }
+
+ return documentData;
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(DataDashAttributeData_Document))]
+ [MemberData(nameof(DataDashAttributeData_CSharpBlock))]
+ public void Rewrite_GeneratesExpectedOutputForUnboundDataDashAttributes(
+ string documentContent,
+ object expectedOutput)
+ {
+ // Act & Assert
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, Enumerable.Empty<RazorDiagnostic>(), "input");
+ }
+
+ public static TheoryData MinimizedAttributeData_Document
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var noErrors = new RazorDiagnostic[0];
+ var stringType = typeof(string).FullName;
+ var intType = typeof(int).FullName;
+ var expressionString = "@DateTime.Now + 1";
+ var expression = new Func<int, SyntaxTreeNode>(index =>
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(index, 0, index)),
+ new SourceLocation(index, 0, index)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ factory.Markup(" +")
+ .With(new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", index + 13, 0, index + 13),
+ value: new LocationTagged<string>("+", index + 14, 0, index + 14))),
+ factory.Markup(" 1")
+ .With(new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", index + 15, 0, index + 15),
+ value: new LocationTagged<string>("1", index + 16, 0, index + 16)))));
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<input unbound-required />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ })),
+ noErrors
+ },
+ {
+ "<p bound-string></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-string />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-int />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<p bound-int></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ }
+ },
+ {
+ "<input int-dictionary/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("int-dictionary", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 14),
+ "int-dictionary",
+ "input",
+ typeof(IDictionary<string, int>).Namespace + ".IDictionary<System.String, System.Int32>"),
+ }
+ },
+ {
+ "<input string-dictionary />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("string-dictionary", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 17),
+ "string-dictionary",
+ "input",
+ typeof(IDictionary<string, string>).Namespace + ".IDictionary<System.String, System.String>"),
+ }
+ },
+ {
+ "<input int-prefix- />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("int-prefix-", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 11),
+ "int-prefix-",
+ "input",
+ intType),
+ RazorDiagnosticFactory.CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(
+ new SourceSpan(7, 0, 7, 11),
+ "int-prefix-",
+ "input"),
+ }
+ },
+ {
+ "<input string-prefix-/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("string-prefix-", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 14),
+ "string-prefix-",
+ "input",
+ stringType),
+ RazorDiagnosticFactory.CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(
+ new SourceSpan(7, 0, 7, 14),
+ "string-prefix-",
+ "input"),
+ }
+ },
+ {
+ "<input int-prefix-value/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("int-prefix-value", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 16),
+ "int-prefix-value",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<input string-prefix-value />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("string-prefix-value", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 19),
+ "string-prefix-value",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<input int-prefix-value='' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("int-prefix-value", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 16),
+ "int-prefix-value",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<input string-prefix-value=''/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("string-prefix-value", new MarkupBlock(), AttributeStructure.SingleQuotes),
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<input int-prefix-value='3'/>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "int-prefix-value",
+ factory.CodeMarkup("3").With(new ExpressionChunkGenerator()),
+ AttributeStructure.SingleQuotes),
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<input string-prefix-value='some string' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode(
+ "string-prefix-value",
+ new MarkupBlock(
+ factory.Markup("some"),
+ factory.Markup(" string")),
+ AttributeStructure.SingleQuotes),
+ })),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<input unbound-required bound-required-string />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(24, 0, 24, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<p bound-int bound-string></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(13, 0, 13, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-int unbound-required bound-required-string />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(43, 0, 43, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<p bound-int bound-string bound-string></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(13, 0, 13, 12),
+ "bound-string",
+ "p",
+ stringType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(26, 0, 26, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input unbound-required class='btn' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ })),
+ noErrors
+ },
+ {
+ "<p bound-string class='btn'></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input class='btn' unbound-required />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ })),
+ noErrors
+ },
+ {
+ "<p class='btn' bound-string></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(15, 0, 15, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-string class='btn' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<input class='btn' bound-required-string />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(19, 0, 19, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-int class='btn' />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<p bound-int class='btn'></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ }
+ },
+ {
+ "<input class='btn' bound-required-int />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(19, 0, 19, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<p class='btn' bound-int></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(15, 0, 15, 9),
+ "bound-int",
+ "p",
+ intType),
+ }
+ },
+ {
+ $"<input class='{expressionString}' bound-required-int />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", expression(14), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(33, 0, 33, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ }
+ },
+ {
+ $"<p class='{expressionString}' bound-int></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", expression(10), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(29, 0, 29, 9),
+ "bound-int",
+ "p",
+ intType),
+ }
+ },
+ {
+ $"<input bound-required-int class='{expressionString}' bound-required-string " +
+ $"class='{expressionString}' unbound-required />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", expression(36), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", expression(86), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(10, 0, 10, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(57, 0, 57, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ $"<p bound-int class='{expressionString}' bound-string " +
+ $"class='{expressionString}' bound-string></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", expression(23), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("class", expression(64), AttributeStructure.SingleQuotes),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(6, 0, 6, 9),
+ "bound-int",
+ "p",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(44, 0, 44, 12),
+ "bound-string",
+ "p",
+ stringType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(84, 0, 84, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ };
+ }
+ }
+
+ public static TheoryData MinimizedAttributeData_CSharpBlock
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var documentData = MinimizedAttributeData_Document;
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+ Action<MarkupBlock> updateDynamicChunkGenerators = (block) =>
+ {
+ var tagHelperBlock = block.Children.First() as MarkupTagHelperBlock;
+
+ for (var i = 0; i < tagHelperBlock.Attributes.Count; i++)
+ {
+ var attribute = tagHelperBlock.Attributes[i];
+ var holderBlock = attribute.Value as Block;
+
+ if (holderBlock == null)
+ {
+ continue;
+ }
+
+ var valueBlock = holderBlock.Children.FirstOrDefault() as Block;
+ if (valueBlock != null)
+ {
+ var chunkGenerator = valueBlock.ChunkGenerator as DynamicAttributeBlockChunkGenerator;
+
+ if (chunkGenerator != null)
+ {
+ var blockBuilder = new BlockBuilder(holderBlock);
+ var expressionBlockBuilder = new BlockBuilder(valueBlock);
+ var newChunkGenerator = new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ chunkGenerator.Prefix.Value,
+ new SourceLocation(
+ chunkGenerator.Prefix.Location.AbsoluteIndex + 2,
+ chunkGenerator.Prefix.Location.LineIndex,
+ chunkGenerator.Prefix.Location.CharacterIndex + 2)),
+ new SourceLocation(
+ chunkGenerator.ValueStart.AbsoluteIndex + 2,
+ chunkGenerator.ValueStart.LineIndex,
+ chunkGenerator.ValueStart.CharacterIndex + 2));
+
+ expressionBlockBuilder.ChunkGenerator = newChunkGenerator;
+ blockBuilder.Children[0] = expressionBlockBuilder.Build();
+
+ for (var j = 1; j < blockBuilder.Children.Count; j++)
+ {
+ var span = blockBuilder.Children[j] as Span;
+ if (span != null)
+ {
+ var literalChunkGenerator =
+ span.ChunkGenerator as LiteralAttributeChunkGenerator;
+
+ var spanBuilder = new SpanBuilder(span);
+ spanBuilder.ChunkGenerator = new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(
+ literalChunkGenerator.Prefix.Value,
+ new SourceLocation(
+ literalChunkGenerator.Prefix.Location.AbsoluteIndex + 2,
+ literalChunkGenerator.Prefix.Location.LineIndex,
+ literalChunkGenerator.Prefix.Location.CharacterIndex + 2)),
+ value: new LocationTagged<string>(
+ literalChunkGenerator.Value.Value,
+ new SourceLocation(
+ literalChunkGenerator.Value.Location.AbsoluteIndex + 2,
+ literalChunkGenerator.Value.Location.LineIndex,
+ literalChunkGenerator.Value.Location.CharacterIndex + 2)));
+
+ blockBuilder.Children[j] = spanBuilder.Build();
+ }
+ }
+
+ tagHelperBlock.Attributes[i] = new TagHelperAttributeNode(
+ attribute.Name,
+ blockBuilder.Build(),
+ attribute.AttributeStructure);
+ }
+ }
+ }
+ };
+
+ foreach (var data in documentData)
+ {
+ data[0] = $"@{{{data[0]}}}";
+
+ updateDynamicChunkGenerators(data[1] as MarkupBlock);
+
+ data[1] = buildStatementBlock(() => data[1] as MarkupBlock);
+
+ var errors = data[2] as RazorDiagnostic[];
+
+ for (var i = 0; i < errors.Length; i++)
+ {
+ var error = errors[i] as DefaultRazorDiagnostic;
+ var currentErrorLocation = new SourceLocation(error.Span.AbsoluteIndex, error.Span.LineIndex, error.Span.CharacterIndex);
+ var newErrorLocation = SourceLocationTracker.Advance(currentErrorLocation, "@{");
+ var copiedDiagnostic = new DefaultRazorDiagnostic(error.Descriptor, new SourceSpan(newErrorLocation, error.Span.Length), error.Args);
+ errors[i] = copiedDiagnostic;
+ }
+ }
+
+ return documentData;
+ }
+ }
+
+ public static TheoryData MinimizedAttributeData_PartialTags
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var noErrors = new RazorDiagnostic[0];
+ var stringType = typeof(string).FullName;
+ var intType = typeof(int).FullName;
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<input unbound-required",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ }
+ },
+ {
+ "<input bound-required-string",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-int",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ }
+ },
+ {
+ "<input bound-required-int unbound-required bound-required-string",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(43, 0, 43, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ }
+ },
+ {
+ "<p bound-string",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<p bound-int",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ }
+ },
+ {
+ "<p bound-int bound-string",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(3, 0, 3, 9),
+ "bound-int",
+ "p",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(13, 0, 13, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ {
+ "<input bound-required-int unbound-required bound-required-string<p bound-int bound-string",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-required-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("unbound-required", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-required-string", null, AttributeStructure.Minimized),
+ },
+ children: new MarkupTagHelperBlock(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("bound-string", null, AttributeStructure.Minimized),
+ }))),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 5), "input"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 18),
+ "bound-required-int",
+ "input",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(43, 0, 43, 21),
+ "bound-required-string",
+ "input",
+ stringType),
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(65, 0, 65), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(65, 0, 65), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(67, 0, 67, 9),
+ "bound-int",
+ "p",
+ intType),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(77, 0, 77, 12),
+ "bound-string",
+ "p",
+ stringType),
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(MinimizedAttributeData_Document))]
+ [MemberData(nameof(MinimizedAttributeData_CSharpBlock))]
+ [MemberData(nameof(MinimizedAttributeData_PartialTags))]
+ public void Rewrite_UnderstandsMinimizedAttributes(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireAttributeDescriptor(attribute => attribute.Name("unbound-required")))
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireAttributeDescriptor(attribute => attribute.Name("bound-required-string")))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound-required-string")
+ .PropertyName("BoundRequiredString")
+ .TypeName(typeof(string).FullName))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("InputTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireAttributeDescriptor(attribute => attribute.Name("bound-required-int")))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound-required-int")
+ .PropertyName("BoundRequiredInt")
+ .TypeName(typeof(int).FullName))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("InputTagHelper3", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("input"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("int-dictionary")
+ .PropertyName("DictionaryOfIntProperty")
+ .TypeName(typeof(IDictionary<string, int>).Namespace + ".IDictionary<System.String, System.Int32>")
+ .AsDictionaryAttribute("int-prefix-", typeof(int).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("string-dictionary")
+ .PropertyName("DictionaryOfStringProperty")
+ .TypeName(typeof(IDictionary<string, string>).Namespace + ".IDictionary<System.String, System.String>")
+ .AsDictionaryAttribute("string-prefix-", typeof(string).FullName))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound-string")
+ .PropertyName("BoundRequiredString")
+ .TypeName(typeof(string).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound-int")
+ .PropertyName("BoundRequiredString")
+ .TypeName(typeof(int).FullName))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors);
+ }
+
+ [Fact]
+ public void Rewrite_UnderstandsMinimizedBooleanBoundAttributes()
+ {
+ // Arrange
+ var documentContent = "<input boundbool boundbooldict-key />";
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("boundbool")
+ .PropertyName("BoundBoolProp")
+ .TypeName(typeof(bool).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("boundbooldict")
+ .PropertyName("BoundBoolDictProp")
+ .TypeName("System.Collections.Generic.IDictionary<string, bool>")
+ .AsDictionary("boundbooldict-", typeof(bool).FullName))
+ .Build(),
+ };
+
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("boundbool", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("boundbooldict-key", null, AttributeStructure.Minimized),
+ }));
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, new RazorDiagnostic[] { });
+ }
+
+ [Fact]
+ public void Rewrite_FeatureDisabled_AddsErrorForMinimizedBooleanBoundAttributes()
+ {
+ // Arrange
+ var documentContent = "<input boundbool boundbooldict-key />";
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("boundbool")
+ .PropertyName("BoundBoolProp")
+ .TypeName(typeof(bool).FullName))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("boundbooldict")
+ .PropertyName("BoundBoolDictProp")
+ .TypeName("System.Collections.Generic.IDictionary<string, bool>")
+ .AsDictionary("boundbooldict-", typeof(bool).FullName))
+ .Build(),
+ };
+
+ var featureFlags = new TestRazorParserFeatureFlags();
+
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "input",
+ TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("boundbool", null, AttributeStructure.Minimized),
+ new TagHelperAttributeNode("boundbooldict-key", null, AttributeStructure.Minimized),
+ }));
+
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(7, 0, 7, 9),
+ "boundbool",
+ "input",
+ "System.Boolean"),
+ RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
+ new SourceSpan(17, 0, 17, 17),
+ "boundbooldict-key",
+ "input",
+ "System.Boolean"),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors, featureFlags: featureFlags);
+ }
+
+ private class TestRazorParserFeatureFlags : RazorParserFeatureFlags
+ {
+ public TestRazorParserFeatureFlags(
+ bool allowMinimizedBooleanTagHelperAttributes = false,
+ bool allowHtmlCommentsInTagHelper = false,
+ bool experimental_AllowConditionalDataDashAttributes = false)
+ {
+ AllowMinimizedBooleanTagHelperAttributes = allowMinimizedBooleanTagHelperAttributes;
+ AllowHtmlCommentsInTagHelpers = allowHtmlCommentsInTagHelper;
+ EXPERIMENTAL_AllowConditionalDataDashAttributes = experimental_AllowConditionalDataDashAttributes;
+ }
+
+ public override bool AllowMinimizedBooleanTagHelperAttributes { get; }
+
+ public override bool AllowHtmlCommentsInTagHelpers { get; }
+
+ public override bool EXPERIMENTAL_AllowConditionalDataDashAttributes { get; }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockTest.cs
new file mode 100644
index 0000000000..971e97f361
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperBlockTest.cs
@@ -0,0 +1,207 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TagHelperBlockTest
+ {
+ [Fact]
+ public void Clone_ClonesTagHelperChildren()
+ {
+ // Arrange
+ var tagHelper = new TagHelperBlockBuilder(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>(),
+ children: new[]
+ {
+ new SpanBuilder(SourceLocation.Zero).Build(),
+ new SpanBuilder(new SourceLocation(0, 1, 2)).Build(),
+ }).Build();
+
+ // Act
+ var copy = (TagHelperBlock)tagHelper.Clone();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(copy, tagHelper);
+ Assert.Collection(
+ copy.Children,
+ child => Assert.NotSame(tagHelper.Children[0], child),
+ child => Assert.NotSame(tagHelper.Children[1], child));
+ }
+
+ [Fact]
+ public void Clone_ClonesTagHelperAttributes()
+ {
+ // Arrange
+ var tagHelper = (TagHelperBlock)new TagHelperBlockBuilder(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>()
+ {
+ new TagHelperAttributeNode("class", new SpanBuilder(SourceLocation.Zero).Build(), AttributeStructure.NoQuotes),
+ new TagHelperAttributeNode("checked", new SpanBuilder(SourceLocation.Undefined).Build(), AttributeStructure.NoQuotes)
+ },
+ children: Enumerable.Empty<SyntaxTreeNode>()).Build();
+
+ // Act
+ var copy = (TagHelperBlock)tagHelper.Clone();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(copy, tagHelper);
+ Assert.Collection(
+ copy.Attributes,
+ attribute => Assert.NotSame(tagHelper.Attributes[0], attribute),
+ attribute => Assert.NotSame(tagHelper.Attributes[1], attribute));
+ }
+
+ [Fact]
+ public void Clone_ClonesTagHelperSourceStartTag()
+ {
+ // Arrange
+ var tagHelper = (TagHelperBlock)new TagHelperBlockBuilder(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>(),
+ children: Enumerable.Empty<SyntaxTreeNode>())
+ {
+ SourceStartTag = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Comment,
+ ChunkGenerator = new RazorCommentChunkGenerator()
+ }.Build()
+ }.Build();
+
+ // Act
+ var copy = (TagHelperBlock)tagHelper.Clone();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(copy, tagHelper);
+ Assert.NotSame(tagHelper.SourceStartTag, copy.SourceStartTag);
+ }
+
+ [Fact]
+ public void Clone_ClonesTagHelperSourceEndTag()
+ {
+ // Arrange
+ var tagHelper = (TagHelperBlock)new TagHelperBlockBuilder(
+ "p",
+ TagMode.StartTagAndEndTag,
+ attributes: new List<TagHelperAttributeNode>(),
+ children: Enumerable.Empty<SyntaxTreeNode>())
+ {
+ SourceEndTag = new BlockBuilder()
+ {
+ Type = BlockKindInternal.Comment,
+ ChunkGenerator = new RazorCommentChunkGenerator()
+ }.Build()
+ }.Build();
+
+ // Act
+ var copy = (TagHelperBlock)tagHelper.Clone();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(copy, tagHelper);
+ Assert.NotSame(tagHelper.SourceEndTag, copy.SourceEndTag);
+ }
+
+ [Fact]
+ public void FlattenFlattensSelfClosingTagHelpers()
+ {
+ // Arrange
+ var spanFactory = new SpanFactory();
+ var blockFactory = new BlockFactory(spanFactory);
+ var tagHelper = (TagHelperBlock)blockFactory.TagHelperBlock(
+ tagName: "input",
+ tagMode: TagMode.SelfClosing,
+ start: SourceLocation.Zero,
+ startTag: blockFactory.MarkupTagBlock("<input />"),
+ children: new SyntaxTreeNode[0],
+ endTag: null);
+ spanFactory.Reset();
+ var expectedNode = spanFactory.Markup("<input />");
+
+ // Act
+ var flattenedNodes = tagHelper.Flatten();
+
+ // Assert
+ var node = Assert.Single(flattenedNodes);
+ Assert.True(node.EquivalentTo(expectedNode));
+ }
+
+ [Fact]
+ public void FlattenFlattensStartAndEndTagTagHelpers()
+ {
+ // Arrange
+ var spanFactory = new SpanFactory();
+ var blockFactory = new BlockFactory(spanFactory);
+ var tagHelper = (TagHelperBlock)blockFactory.TagHelperBlock(
+ tagName: "div",
+ tagMode: TagMode.StartTagAndEndTag,
+ start: SourceLocation.Zero,
+ startTag: blockFactory.MarkupTagBlock("<div>"),
+ children: new SyntaxTreeNode[0],
+ endTag: blockFactory.MarkupTagBlock("</div>"));
+ spanFactory.Reset();
+ var expectedStartTag = spanFactory.Markup("<div>");
+ var expectedEndTag = spanFactory.Markup("</div>");
+
+ // Act
+ var flattenedNodes = tagHelper.Flatten();
+
+ // Assert
+ Assert.Collection(
+ flattenedNodes,
+ first =>
+ {
+ Assert.True(first.EquivalentTo(expectedStartTag));
+ },
+ second =>
+ {
+ Assert.True(second.EquivalentTo(expectedEndTag));
+ });
+ }
+
+ [Fact]
+ public void FlattenFlattensStartAndEndTagWithChildrenTagHelpers()
+ {
+ // Arrange
+ var spanFactory = new SpanFactory();
+ var blockFactory = new BlockFactory(spanFactory);
+ var tagHelper = (TagHelperBlock)blockFactory.TagHelperBlock(
+ tagName: "div",
+ tagMode: TagMode.StartTagAndEndTag,
+ start: SourceLocation.Zero,
+ startTag: blockFactory.MarkupTagBlock("<div>"),
+ children: new SyntaxTreeNode[] { spanFactory.Markup("Hello World") },
+ endTag: blockFactory.MarkupTagBlock("</div>"));
+ spanFactory.Reset();
+ var expectedStartTag = spanFactory.Markup("<div>");
+ var expectedChildren = spanFactory.Markup("Hello World");
+ var expectedEndTag = spanFactory.Markup("</div>");
+
+ // Act
+ var flattenedNodes = tagHelper.Flatten();
+
+ // Assert
+ Assert.Collection(
+ flattenedNodes,
+ first =>
+ {
+ Assert.True(first.EquivalentTo(expectedStartTag));
+ },
+ second =>
+ {
+ Assert.True(second.EquivalentTo(expectedChildren));
+ },
+ third =>
+ {
+ Assert.True(third.EquivalentTo(expectedEndTag));
+ });
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs
new file mode 100644
index 0000000000..3f37c82c4d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperParseTreeRewriterTest.cs
@@ -0,0 +1,4346 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TagHelperParseTreeRewriterTest : TagHelperRewritingTestBase
+ {
+ public static TheoryData GetAttributeNameValuePairsData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ Func<string, string, KeyValuePair<string, string>> kvp =
+ (key, value) => new KeyValuePair<string, string>(key, value);
+ var empty = Enumerable.Empty<KeyValuePair<string, string>>();
+ var csharp = TagHelperParseTreeRewriter.InvalidAttributeValueMarker;
+
+ // documentContent, expectedPairs
+ return new TheoryData<string, IEnumerable<KeyValuePair<string, string>>>
+ {
+ { "<a>", empty },
+ { "<a @{ } href='~/home'>", empty },
+ { "<a href=\"@true\">", new[] { kvp("href", csharp) } },
+ { "<a href=\"prefix @true suffix\">", new[] { kvp("href", $"prefix{csharp} suffix") } },
+ { "<a href=~/home>", new[] { kvp("href", "~/home") } },
+ { "<a href=~/home @{ } nothing='something'>", new[] { kvp("href", "~/home"), kvp("", "") } },
+ {
+ "<a href=\"@DateTime.Now::0\" class='btn btn-success' random>",
+ new[] { kvp("href", $"{csharp}::0"), kvp("class", "btn btn-success"), kvp("random", "") }
+ },
+ { "<a href=>", new[] { kvp("href", "") } },
+ { "<a href='\"> ", new[] { kvp("href", "\">") } },
+ { "<a href'", new[] { kvp("href'", "") } },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAttributeNameValuePairsData))]
+ public void GetAttributeNameValuePairs_ParsesPairsCorrectly(
+ string documentContent,
+ IEnumerable<KeyValuePair<string, string>> expectedPairs)
+ {
+ // Arrange
+ var errorSink = new ErrorSink();
+ var parseResult = ParseDocument(documentContent);
+ var document = parseResult.Root;
+ var parseTreeRewriter = new TagHelperParseTreeRewriter(null, Enumerable.Empty<TagHelperDescriptor>(), parseResult.Options.FeatureFlags);
+
+ // Assert - Guard
+ var rootBlock = Assert.IsType<Block>(document);
+ var child = Assert.Single(rootBlock.Children);
+ var tagBlock = Assert.IsType<Block>(child);
+ Assert.Equal(BlockKindInternal.Tag, tagBlock.Type);
+ Assert.Empty(errorSink.Errors);
+
+ // Act
+ var pairs = parseTreeRewriter.GetAttributeNameValuePairs(tagBlock);
+
+ // Assert
+ Assert.Equal(expectedPairs, pairs);
+ }
+
+ public static TheoryData PartialRequiredParentData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ Func<int, string, RazorDiagnostic> errorFormatUnclosed = (location, tagName) =>
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(location, 0, location), tagName.Length), tagName);
+
+ Func<int, string, RazorDiagnostic> errorFormatNoCloseAngle = (location, tagName) =>
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(location, 0, location), tagName.Length), tagName);
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<p><strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong"))),
+ new[] { errorFormatUnclosed(1, "p"), errorFormatUnclosed(4, "strong") }
+ },
+ {
+ "<p><strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong"))),
+ new[] { errorFormatUnclosed(1, "p") }
+ },
+ {
+ "<p><strong></p><strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong")),
+ new MarkupTagHelperBlock("strong")),
+ new[] { errorFormatUnclosed(4, "strong"), errorFormatUnclosed(16, "strong") }
+ },
+ {
+ "<<p><<strong></</strong</strong></p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("strong",
+ blockFactory.MarkupTagBlock("</")),
+ blockFactory.MarkupTagBlock("</strong>"))),
+ new[] { errorFormatNoCloseAngle(17, "strong"), errorFormatUnclosed(25, "strong") }
+ },
+ {
+ "<<p><<strong></</strong></strong></p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("strong",
+ blockFactory.MarkupTagBlock("</")),
+ blockFactory.MarkupTagBlock("</strong>"))),
+ new[] { errorFormatUnclosed(26, "strong") }
+ },
+
+ {
+ "<<p><<custom></<</custom></custom></p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<"),
+ new MarkupTagHelperBlock("custom",
+ blockFactory.MarkupTagBlock("</"),
+ blockFactory.MarkupTagBlock("<")),
+ blockFactory.MarkupTagBlock("</custom>"))),
+ new[] { errorFormatUnclosed(27, "custom") }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(PartialRequiredParentData))]
+ public void Rewrite_UnderstandsPartialRequiredParentTags(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("CatchALlTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors);
+ }
+
+ public static TheoryData NestedVoidSelfClosingRequiredParentData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<input><strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"))
+ },
+ {
+ "<p><input><strong></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ new MarkupTagHelperBlock("strong")))
+ },
+ {
+ "<p><br><strong></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<br>"),
+ new MarkupTagHelperBlock("strong")))
+ },
+ {
+ "<p><p><br></p><strong></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<br>")),
+ new MarkupTagHelperBlock("strong")))
+ },
+ {
+ "<input><strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("input", TagMode.StartTagOnly),
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"))
+ },
+ {
+ "<p><input /><strong /></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("input", TagMode.SelfClosing),
+ new MarkupTagHelperBlock("strong", TagMode.SelfClosing)))
+ },
+ {
+ "<p><br /><strong /></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<br />"),
+ new MarkupTagHelperBlock("strong", TagMode.SelfClosing)))
+ },
+ {
+ "<p><p><br /></p><strong /></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<br />")),
+ new MarkupTagHelperBlock("strong", TagMode.SelfClosing)))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NestedVoidSelfClosingRequiredParentData))]
+ public void Rewrite_UnderstandsNestedVoidSelfClosingRequiredParent(
+ string documentContent,
+ object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("p"))
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("input"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData NestedRequiredParentData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<strong></strong>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"))
+ },
+ {
+ "<p><strong></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong")))
+ },
+ {
+ "<div><strong></strong></div>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<div>"),
+ new MarkupTagHelperBlock("strong"),
+ blockFactory.MarkupTagBlock("</div>"))
+ },
+ {
+ "<strong><strong></strong></strong>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ blockFactory.MarkupTagBlock("</strong>"))
+ },
+ {
+ "<p><strong><strong></strong></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"))))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NestedRequiredParentData))]
+ public void Rewrite_UnderstandsNestedRequiredParent(string documentContent, object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("p"))
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("div"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ [Fact]
+ public void Rewrite_UnderstandsTagHelperPrefixAndAllowedChildren()
+ {
+ // Arrange
+ var documentContent = "<th:p><th:strong></th:strong></th:p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("th:p",
+ new MarkupTagHelperBlock("th:strong")));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ documentContent,
+ expectedOutput,
+ expectedErrors: Enumerable.Empty<RazorDiagnostic>(),
+ tagHelperPrefix: "th:");
+ }
+
+ [Fact]
+ public void Rewrite_UnderstandsTagHelperPrefixAndAllowedChildrenAndRequireParent()
+ {
+ // Arrange
+ var documentContent = "<th:p><th:strong></th:strong></th:p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("th:p",
+ new MarkupTagHelperBlock("th:strong")));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong").RequireParentTag("p"))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ documentContent,
+ expectedOutput,
+ expectedErrors: Enumerable.Empty<RazorDiagnostic>(),
+ tagHelperPrefix: "th:");
+ }
+
+ [Fact]
+ public void Rewrite_InvalidStructure_UnderstandsTagHelperPrefixAndAllowedChildrenAndRequireParent()
+ {
+ // Arrange
+ var documentContent = "<th:p></th:strong></th:p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("th:p",
+ new MarkupTagBlock(
+ Factory.Markup("</th:strong>"))));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong").RequireParentTag("p"))
+ .Build(),
+ };
+ var expectedErrors = new[] {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(filePath: null, absoluteIndex: 8, lineIndex: 0, characterIndex: 8, length: 9),
+ "th:strong"),
+ };
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ documentContent,
+ expectedOutput,
+ expectedErrors: expectedErrors,
+ tagHelperPrefix: "th:");
+ }
+
+ [Fact]
+ public void Rewrite_NonTagHelperChild_UnderstandsTagHelperPrefixAndAllowedChildren()
+ {
+ // Arrange
+ var documentContent = "<th:p><strong></strong></th:p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("th:p",
+ new MarkupTagBlock(
+ Factory.Markup("<strong>")),
+ new MarkupTagBlock(
+ Factory.Markup("</strong>"))));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ documentContent,
+ expectedOutput,
+ expectedErrors: Enumerable.Empty<RazorDiagnostic>(),
+ tagHelperPrefix: "th:");
+ }
+
+ public static TheoryData InvalidHtmlScriptBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<script type><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(factory.Markup(" type")),
+ factory.Markup(">")),
+ factory.Markup("<input />"),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script types='text/html'><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "types",
+ prefix: new LocationTagged<string>(" types='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 24, 0, 24)),
+ factory.Markup(" types='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 15, 0, 15),
+ value: new LocationTagged<string>("text/html", 15, 0, 15))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("<input />"),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script type='text/html invalid'><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 31, 0, 31)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
+ value: new LocationTagged<string>("text/html", 14, 0, 14))),
+ factory.Markup(" invalid").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 23, 0, 23),
+ value: new LocationTagged<string>("invalid", 24, 0, 24))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("<input />"),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script type='text/ng-*' type='text/html'><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 23, 0, 23)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/ng-*").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
+ value: new LocationTagged<string>("text/ng-*", 14, 0, 14))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 24, 0, 24),
+ suffix: new LocationTagged<string>("'", 40, 0, 40)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 31, 0, 31),
+ value: new LocationTagged<string>("text/html", 31, 0, 31))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("<input />"),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(InvalidHtmlScriptBlockData))]
+ public void TagHelperParseTreeRewriter_DoesNotUnderstandTagHelpersInInvalidHtmlTypedScriptTags(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "input");
+ }
+
+ public static TheoryData HtmlScriptBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<script type='text/html'><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 23, 0, 23)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
+ value: new LocationTagged<string>("text/html", 14, 0, 14))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ new MarkupTagHelperBlock("input", TagMode.SelfClosing),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script id='scriptTag' type='text/html' class='something'><input /></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "id",
+ prefix: new LocationTagged<string>(" id='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 21, 0, 21)),
+ factory.Markup(" id='").With(SpanChunkGenerator.Null),
+ factory.Markup("scriptTag").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
+ value: new LocationTagged<string>("scriptTag", 12, 0, 12))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 22, 0, 22),
+ suffix: new LocationTagged<string>("'", 38, 0, 38)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 29, 0, 29),
+ value: new LocationTagged<string>("text/html", 29, 0, 29))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 39, 0, 39),
+ suffix: new LocationTagged<string>("'", 56, 0, 56)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("something").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 47, 0, 47),
+ value: new LocationTagged<string>("something", 47, 0, 47))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ new MarkupTagHelperBlock("input", TagMode.SelfClosing),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script type='text/html'><p><script type='text/html'><input /></script></p></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 23, 0, 23)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
+ value: new LocationTagged<string>("text/html", 14, 0, 14))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ new MarkupTagHelperBlock("p",
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 35, 0, 35),
+ suffix: new LocationTagged<string>("'", 51, 0, 51)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 42, 0, 42),
+ value: new LocationTagged<string>("text/html", 42, 0, 42))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ new MarkupTagHelperBlock("input", TagMode.SelfClosing),
+ blockFactory.MarkupTagBlock("</script>")),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ {
+ "<script type='text/html'><p><script type='text/ html'><input /></script></p></script>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 7, 0, 7),
+ suffix: new LocationTagged<string>("'", 23, 0, 23)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 14, 0, 14),
+ value: new LocationTagged<string>("text/html", 14, 0, 14))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ new MarkupTagHelperBlock("p",
+ new MarkupTagBlock(
+ factory.Markup("<script"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "type",
+ prefix: new LocationTagged<string>(" type='", 35, 0, 35),
+ suffix: new LocationTagged<string>("'", 52, 0, 52)),
+ factory.Markup(" type='").With(SpanChunkGenerator.Null),
+ factory.Markup("text/").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 42, 0, 42),
+ value: new LocationTagged<string>("text/", 42, 0, 42))),
+ factory.Markup(" html").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 47, 0, 47),
+ value: new LocationTagged<string>("html", 48, 0, 48))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("<input />"),
+ blockFactory.MarkupTagBlock("</script>")),
+ blockFactory.MarkupTagBlock("</script>"))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(HtmlScriptBlockData))]
+ public void TagHelperParseTreeRewriter_UnderstandsTagHelpersInHtmlTypedScriptTags(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p", "input");
+ }
+
+ [Fact]
+ public void Rewrite_CanHandleInvalidChildrenWithWhitespace()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var documentContent = $"<p>{Environment.NewLine} <strong>{Environment.NewLine} Hello" +
+ $"{Environment.NewLine} </strong>{Environment.NewLine}</p>";
+ var newLineLength = Environment.NewLine.Length;
+ var expectedErrors = new[] {
+ RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
+ new SourceSpan(absoluteIndex: 8 + newLineLength, lineIndex: 1, characterIndex: 5, length: 6), "strong", "p", "br"),
+ };
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup(Environment.NewLine + " "),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup(Environment.NewLine + " Hello" + Environment.NewLine + " "),
+ blockFactory.MarkupTagBlock("</strong>"),
+ factory.Markup(Environment.NewLine)));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("br")
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors);
+ }
+
+ [Fact]
+ public void Rewrite_RecoversWhenRequiredAttributeMismatchAndRestrictedChildren()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var documentContent = "<strong required><strong></strong></strong>";
+
+ var expectedErrors = new[] {
+ RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
+ new SourceSpan(absoluteIndex: 18, lineIndex: 0, characterIndex: 18, length: 6), "strong", "strong", "br")
+ };
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("strong",
+ new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("required", null, AttributeStructure.Minimized)
+ },
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>")));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireAttributeDescriptor(attribute => attribute.Name("required")))
+ .AllowChildTag("br")
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors);
+ }
+
+ [Fact]
+ public void Rewrite_CanHandleMultipleTagHelpersWithAllowedChildren_OneNull()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var documentContent = "<p><strong>Hello World</strong><br></p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("Hello World")),
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly)));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .AllowChildTag("br")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("BRTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("br")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ [Fact]
+ public void Rewrite_CanHandleMultipleTagHelpersWithAllowedChildren()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var documentContent = "<p><strong>Hello World</strong><br></p>";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("Hello World")),
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly)));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("strong")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("PTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("br")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("BRTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("br")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData AllowedChildrenData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ Func<string, string, string, int, int, RazorDiagnostic> nestedTagError =
+ (childName, parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), childName, parentName, allowed);
+ Func<string, string, int, int, RazorDiagnostic> nestedContentError =
+ (parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), parentName, allowed);
+
+ return new TheoryData<string, IEnumerable<string>, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<p><br /></p>",
+ new[] { "br" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing))),
+ new RazorDiagnostic[0]
+ },
+ {
+ $"<p>{Environment.NewLine}<br />{Environment.NewLine}</p>",
+ new[] { "br" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup(Environment.NewLine),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup(Environment.NewLine))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p><br></p>",
+ new[] { "strong" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly))),
+ new[] { nestedTagError("br", "p", "strong", 4, 2) }
+ },
+ {
+ "<p>Hello</p>",
+ new[] { "strong" },
+ new MarkupBlock(new MarkupTagHelperBlock("p", factory.Markup("Hello"))),
+ new[] { nestedContentError("p", "strong", 3, 5) }
+ },
+ {
+ "<p><hr /></p>",
+ new[] { "br", "strong" },
+ new MarkupBlock(new MarkupTagHelperBlock("p", blockFactory.MarkupTagBlock("<hr />"))),
+ new[] { nestedTagError("hr", "p", "br, strong", 4, 2) }
+ },
+ {
+ "<p><br>Hello</p>",
+ new[] { "strong" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly),
+ factory.Markup("Hello"))),
+ new[] { nestedTagError("br", "p", "strong", 4, 2), nestedContentError("p", "strong", 7, 5) }
+ },
+ {
+ "<p><strong>Title:</strong><br />Something</p>",
+ new[] { "strong" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong", factory.Markup("Title:")),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup("Something"))),
+ new[]
+ {
+ nestedContentError("strong", "strong", 11, 6),
+ nestedTagError("br", "p", "strong", 27, 2),
+ nestedContentError("p", "strong", 32, 9),
+ }
+ },
+ {
+ "<p><strong>Title:</strong><br />Something</p>",
+ new[] { "strong", "br" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong", factory.Markup("Title:")),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup("Something"))),
+ new[]
+ {
+ nestedContentError("strong", "strong, br", 11, 6),
+ nestedContentError("p", "strong, br", 32, 9),
+ }
+ },
+ {
+ "<p> <strong>Title:</strong> <br /> Something</p>",
+ new[] { "strong", "br" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("strong", factory.Markup("Title:")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup(" Something"))),
+ new[]
+ {
+ nestedContentError("strong", "strong, br", 13, 6),
+ nestedContentError("p", "strong, br", 38, 9),
+ }
+ },
+ {
+ "<p><strong>Title:<br><em>A Very Cool</em></strong><br />Something</p>",
+ new[] { "strong" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("Title:"),
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly),
+ blockFactory.MarkupTagBlock("<em>"),
+ factory.Markup("A Very Cool"),
+ blockFactory.MarkupTagBlock("</em>")),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup("Something"))),
+ new[]
+ {
+ nestedContentError("strong", "strong", 11, 6),
+ nestedTagError("br", "strong", "strong", 18, 2),
+ nestedTagError("em", "strong", "strong", 22, 2),
+ nestedTagError("br", "p", "strong", 51, 2),
+ nestedContentError("p", "strong", 56, 9)
+ }
+ },
+ {
+ "<p><custom>Title:<br><em>A Very Cool</em></custom><br />Something</p>",
+ new[] { "custom" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<custom>"),
+ factory.Markup("Title:"),
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly),
+ blockFactory.MarkupTagBlock("<em>"),
+ factory.Markup("A Very Cool"),
+ blockFactory.MarkupTagBlock("</em>"),
+ blockFactory.MarkupTagBlock("</custom>"),
+ new MarkupTagHelperBlock("br", TagMode.SelfClosing),
+ factory.Markup("Something"))),
+ new[]
+ {
+ nestedTagError("br", "p", "custom", 51, 2),
+ nestedContentError("p", "custom", 56, 9)
+ }
+ },
+ {
+ "<p></</p>",
+ new[] { "custom" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("</"))),
+ new[]
+ {
+ nestedContentError("p", "custom", 3, 2),
+ }
+ },
+ {
+ "<p><</p>",
+ new[] { "custom" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<"))),
+ new[]
+ {
+ nestedContentError("p", "custom", 3, 1),
+ }
+ },
+ {
+ "<p><custom><br>:<strong><strong>Hello</strong></strong>:<input></custom></p>",
+ new[] { "custom", "strong" },
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<custom>"),
+ new MarkupTagHelperBlock("br", TagMode.StartTagOnly),
+ factory.Markup(":"),
+ new MarkupTagHelperBlock("strong",
+ new MarkupTagHelperBlock("strong",
+ factory.Markup("Hello"))),
+ factory.Markup(":"),
+ blockFactory.MarkupTagBlock("<input>"),
+ blockFactory.MarkupTagBlock("</custom>"))),
+ new[]
+ {
+ nestedContentError("strong", "custom, strong", 32, 5),
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(AllowedChildrenData))]
+ public void Rewrite_UnderstandsAllowedChildren(
+ string documentContent,
+ IEnumerable<string> allowedChildren,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ // Arrange
+ var pTagHelperBuilder = TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ var strongTagHelperBuilder = TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("strong"));
+
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ strongTagHelperBuilder.AllowChildTag(childTag);
+ }
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build(),
+ strongTagHelperBuilder.Build(),
+ TagHelperDescriptorBuilder.Create("BRTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("br")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors);
+ }
+
+ [Fact]
+ public void Rewrite_AllowsSimpleHtmlCommentsAsChildren()
+ {
+ // Arrange
+ IEnumerable<string> allowedChildren = new List<string> { "b" };
+ string literal = "asdf";
+ string commentOutput = "Hello World";
+ string expectedOutput = $"<p><b>{literal}</b><!--{commentOutput}--></p>";
+
+ var pTagHelperBuilder = TagHelperDescriptorBuilder
+ .Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ }
+
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build()
+ };
+
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ var expectedMarkup = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<b>"),
+ factory.Markup(literal),
+ blockFactory.MarkupTagBlock("</b>"),
+ blockFactory.HtmlCommentBlock(commentOutput)));
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ expectedOutput,
+ expectedMarkup,
+ Array.Empty<RazorDiagnostic>());
+ }
+
+ [Fact]
+ public void Rewrite_DoesntAllowSimpleHtmlCommentsAsChildrenWhenFeatureFlagIsOff()
+ {
+ // Arrange
+ Func<string, string, string, int, int, RazorDiagnostic> nestedTagError =
+ (childName, parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), childName, parentName, allowed);
+ Func<string, string, int, int, RazorDiagnostic> nestedContentError =
+ (parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), parentName, allowed);
+
+ IEnumerable<string> allowedChildren = new List<string> { "b" };
+ string comment1 = "Hello";
+ string expectedOutput = $"<p><!--{comment1}--></p>";
+
+ var pTagHelperBuilder = TagHelperDescriptorBuilder
+ .Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ }
+
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build()
+ };
+
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ var expectedMarkup = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.HtmlCommentBlock(comment1)));
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ expectedOutput,
+ expectedMarkup,
+ new[]
+ {
+ nestedContentError("p", "b", 3, 4),
+ nestedContentError("p", "b", 7, 5),
+ nestedContentError("p", "b", 12, 3),
+ },
+ featureFlags: RazorParserFeatureFlags.Create(RazorLanguageVersion.Version_2_0));
+ }
+
+ [Fact]
+ public void Rewrite_FailsForContentWithCommentsAsChildren()
+ {
+ // Arrange
+ Func<string, string, string, int, int, RazorDiagnostic> nestedTagError =
+ (childName, parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_InvalidNestedTag(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), childName, parentName, allowed);
+ Func<string, string, int, int, RazorDiagnostic> nestedContentError =
+ (parentName, allowed, location, length) =>
+ RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
+ new SourceSpan(absoluteIndex: location, lineIndex: 0, characterIndex: location, length: length), parentName, allowed);
+
+ IEnumerable<string> allowedChildren = new List<string> { "b" };
+ string comment1 = "Hello";
+ string literal = "asdf";
+ string comment2 = "World";
+ string expectedOutput = $"<p><!--{comment1}-->{literal}<!--{comment2}--></p>";
+
+ var pTagHelperBuilder = TagHelperDescriptorBuilder
+ .Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ }
+
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build()
+ };
+
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ var expectedMarkup = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.HtmlCommentBlock(comment1),
+ factory.Markup(literal),
+ blockFactory.HtmlCommentBlock(comment2)));
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ expectedOutput,
+ expectedMarkup,
+ new[]
+ {
+ nestedContentError("p", "b", 15, 4),
+ });
+ }
+
+ [Fact]
+ public void Rewrite_AllowsRazorCommentsAsChildren()
+ {
+ // Arrange
+ IEnumerable<string> allowedChildren = new List<string> { "b" };
+ string literal = "asdf";
+ string commentOutput = $"@*{literal}*@";
+ string expectedOutput = $"<p><b>{literal}</b>{commentOutput}</p>";
+
+ var pTagHelperBuilder = TagHelperDescriptorBuilder
+ .Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ }
+
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build()
+ };
+
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ var expectedMarkup = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<b>"),
+ factory.Markup(literal),
+ blockFactory.MarkupTagBlock("</b>"),
+ new CommentBlock(
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.Span(SpanKindInternal.Comment, new HtmlSymbol(literal, HtmlSymbolType.RazorComment)).Accepts(AcceptedCharactersInternal.Any),
+ Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharactersInternal.None),
+ Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition).Accepts(AcceptedCharactersInternal.None))));
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ expectedOutput,
+ expectedMarkup,
+ Array.Empty<RazorDiagnostic>());
+ }
+
+ [Fact]
+ public void Rewrite_AllowsRazorMarkupInHtmlComment()
+ {
+ // Arrange
+ IEnumerable<string> allowedChildren = new List<string> { "b" };
+ string literal = "asdf";
+ string part1 = "Hello ";
+ string part2 = "World";
+ string commentStart = "<!--";
+ string commentEnd = "-->";
+ string expectedOutput = $"<p><b>{literal}</b>{commentStart}{part1}@{part2}{commentEnd}</p>";
+
+ var pTagHelperBuilder = TagHelperDescriptorBuilder
+ .Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"));
+ foreach (var childTag in allowedChildren)
+ {
+ pTagHelperBuilder.AllowChildTag(childTag);
+ }
+
+ var descriptors = new TagHelperDescriptor[]
+ {
+ pTagHelperBuilder.Build()
+ };
+
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ var expectedMarkup = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<b>"),
+ factory.Markup(literal),
+ blockFactory.MarkupTagBlock("</b>"),
+ BlockFactory.HtmlCommentBlock(factory, f => new SyntaxTreeNode[] {
+ f.Markup(part1).Accepts(AcceptedCharactersInternal.WhiteSpace),
+ new ExpressionBlock(
+ f.CodeTransition(),
+ f.Code(part2)
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)) })));
+
+ // Act & Assert
+ EvaluateData(
+ descriptors,
+ expectedOutput,
+ expectedMarkup,
+ Array.Empty<RazorDiagnostic>());
+ }
+
+ [Fact]
+ public void Rewrite_UnderstandsNullTagNameWithAllowedChildrenForCatchAll()
+ {
+ // Arrange
+ var documentContent = "<p></</p>";
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("custom")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
+ .Build(),
+ };
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ BlockFactory.MarkupTagBlock("</")));
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
+ new SourceSpan(absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 2), "p", "custom")
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors);
+ }
+
+ [Fact]
+ public void Rewrite_UnderstandsNullTagNameWithAllowedChildrenForCatchAllWithPrefix()
+ {
+ // Arrange
+ var documentContent = "<th:p></</th:p>";
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("PTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .AllowChildTag("custom")
+ .Build(),
+ TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
+ .Build(),
+ };
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagHelperBlock("th:p",
+ BlockFactory.MarkupTagBlock("</")));
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateTagHelper_CannotHaveNonTagContent(
+ new SourceSpan(absoluteIndex: 6, lineIndex: 0, characterIndex: 6, length: 2), "th:p", "custom")
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors, "th:");
+ }
+
+ [Fact]
+ public void Rewrite_CanHandleStartTagOnlyTagTagMode()
+ {
+ // Arrange
+ var documentContent = "<input>";
+ var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ [Fact]
+ public void Rewrite_CreatesErrorForWithoutEndTagTagStructureForEndTags()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var expectedError = RazorDiagnosticFactory.CreateParsing_TagHelperMustNotHaveAnEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 2, lineIndex: 0, characterIndex: 2, length: 5),
+ "input",
+ "InputTagHelper",
+ TagStructure.WithoutEndTag);
+ var documentContent = "</input>";
+ var expectedOutput = new MarkupBlock(blockFactory.MarkupTagBlock("</input>"));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors: new[] { expectedError });
+ }
+
+ [Fact]
+ public void Rewrite_CreatesErrorForInconsistentTagStructures()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var expectedError = RazorDiagnosticFactory.CreateTagHelper_InconsistentTagStructure(
+ new SourceSpan(absoluteIndex: 0, lineIndex: 0, characterIndex: 0, length: 7), "InputTagHelper1", "InputTagHelper2", "input");
+ var documentContent = "<input>";
+ var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly));
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("InputTagHelper1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.WithoutEndTag))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("InputTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireTagStructure(TagStructure.NormalOrSelfClosing))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, expectedOutput, expectedErrors: new[] { expectedError });
+ }
+
+ public static TheoryData RequiredAttributeData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNow = new Func<int, SyntaxTreeNode>(index =>
+ new MarkupBlock(
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(
+ string.Empty,
+ new SourceLocation(index, 0, index)),
+ new SourceLocation(index, 0, index)),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)))));
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<p />",
+ new MarkupBlock(blockFactory.MarkupTagBlock("<p />"))
+ },
+ {
+ "<p></p>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>"))
+ },
+ {
+ "<div />",
+ new MarkupBlock(blockFactory.MarkupTagBlock("<div />"))
+ },
+ {
+ "<div></div>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<div>"),
+ blockFactory.MarkupTagBlock("</div>"))
+ },
+ {
+ "<p class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ }))
+ },
+ {
+ "<p class=\"@DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10))
+ }))
+ },
+ {
+ "<p class=\"btn\">words and spaces</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<p class=\"@DateTime.Now\">words and spaces</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", dateTimeNow(10))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<p class=\"btn\">words<strong>and</strong>spaces</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new SyntaxTreeNode[]
+ {
+ factory.Markup("words"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("and"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ factory.Markup("spaces")
+ }))
+ },
+ {
+ "<strong catchAll=\"hi\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ }))
+ },
+ {
+ "<strong catchAll=\"@DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", dateTimeNow(18))
+ }))
+ },
+ {
+ "<strong catchAll=\"hi\">words and spaces</strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<strong catchAll=\"@DateTime.Now\">words and spaces</strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", dateTimeNow(18))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 4, 0, 4),
+ suffix: new LocationTagged<string>("\"", 15, 0, 15)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
+ value: new LocationTagged<string>("btn", 12, 0, 12))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" />")))
+ },
+ {
+ "<div class=\"btn\"></div>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<div"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 4, 0, 4),
+ suffix: new LocationTagged<string>("\"", 15, 0, 15)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
+ value: new LocationTagged<string>("btn", 12, 0, 12))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ blockFactory.MarkupTagBlock("</div>"))
+ },
+ {
+ "<p notRequired=\"a\" class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("a")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ }))
+ },
+ {
+ "<p notRequired=\"@DateTime.Now\" class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", dateTimeNow(16)),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ }))
+ },
+ {
+ "<p notRequired=\"a\" class=\"btn\">words and spaces</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("a")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"\" class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ }))
+ },
+ {
+ "<div style=\"@DateTime.Now\" class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", dateTimeNow(12)),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ }))
+ },
+ {
+ "<div style=\"\" class=\"btn\">words and spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"@DateTime.Now\" class=\"@DateTime.Now\">words and spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", dateTimeNow(12)),
+ new TagHelperAttributeNode("class", dateTimeNow(34))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"\" class=\"btn\">words<strong>and</strong>spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new SyntaxTreeNode[]
+ {
+ factory.Markup("words"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("and"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ factory.Markup("spaces")
+ }))
+ },
+ {
+ "<p class=\"btn\" catchAll=\"hi\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ }))
+ },
+ {
+ "<p class=\"btn\" catchAll=\"hi\">words and spaces</p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"\" class=\"btn\" catchAll=\"hi\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ }))
+ },
+ {
+ "<div style=\"\" class=\"btn\" catchAll=\"hi\" >words and spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"\" class=\"btn\" catchAll=\"@@hi\" >words and spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll",
+ new MarkupBlock(
+ new MarkupBlock(
+ factory.Markup("@").Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("hi"))),
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"@DateTime.Now\" class=\"@DateTime.Now\" catchAll=\"@DateTime.Now\" >words and " +
+ "spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", dateTimeNow(12)),
+ new TagHelperAttributeNode("class", dateTimeNow(34)),
+ new TagHelperAttributeNode("catchAll", dateTimeNow(59))
+ },
+ children: factory.Markup("words and spaces")))
+ },
+ {
+ "<div style=\"\" class=\"btn\" catchAll=\"hi\" >words<strong>and</strong>spaces</div>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "div",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("style", new MarkupBlock()),
+ new TagHelperAttributeNode("class", factory.Markup("btn")),
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new SyntaxTreeNode[]
+ {
+ factory.Markup("words"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("and"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ factory.Markup("spaces")
+ }))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(RequiredAttributeData))]
+ public void Rewrite_RequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly(
+ string documentContent,
+ object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("pTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("p")
+ .RequireAttributeDescriptor(attribute => attribute.Name("class")))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("divTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("div")
+ .RequireAttributeDescriptor(attribute => attribute.Name("class"))
+ .RequireAttributeDescriptor(attribute => attribute.Name("style")))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("catchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("*")
+ .RequireAttributeDescriptor(attribute => attribute.Name("catchAll")))
+ .Build()
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData NestedRequiredAttributeData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var dateTimeNow = new MarkupBlock(
+ new MarkupBlock(
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))));
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<p class=\"btn\"><p></p></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>")
+ }))
+ },
+ {
+ "<strong catchAll=\"hi\"><strong></strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new SyntaxTreeNode[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ }))
+ },
+ {
+ "<p class=\"btn\"><strong><p></p></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ }))
+ },
+ {
+ "<strong catchAll=\"hi\"><p><strong></strong></p></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new SyntaxTreeNode[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ blockFactory.MarkupTagBlock("</p>"),
+ }))
+ },
+ {
+ "<p class=\"btn\"><strong catchAll=\"hi\"><p></p></strong></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>")
+ })))
+ },
+ {
+ "<strong catchAll=\"hi\"><p class=\"btn\"><strong></strong></p></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ })))
+ },
+ {
+ "<p class=\"btn\"><p class=\"btn\"><p></p></p></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>")
+ })))
+ },
+ {
+ "<strong catchAll=\"hi\"><strong catchAll=\"hi\"><strong></strong></strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ })))
+ },
+ {
+ "<p class=\"btn\"><p><p><p class=\"btn\"><p></p></p></p></p></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("<p>"),
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p>")
+ }),
+ blockFactory.MarkupTagBlock("</p>"),
+ blockFactory.MarkupTagBlock("</p>"),
+ }))
+ },
+ {
+ "<strong catchAll=\"hi\"><strong><strong><strong catchAll=\"hi\"><strong></strong></strong>" +
+ "</strong></strong></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ new MarkupTagHelperBlock(
+ "strong",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("catchAll", factory.Markup("hi"))
+ },
+ children: new[]
+ {
+ blockFactory.MarkupTagBlock("<strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ }),
+ blockFactory.MarkupTagBlock("</strong>"),
+ blockFactory.MarkupTagBlock("</strong>"),
+ }))
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NestedRequiredAttributeData))]
+ public void Rewrite_NestedRequiredAttributeDescriptorsCreateTagHelperBlocksCorrectly(
+ string documentContent,
+ object expectedOutput)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("pTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("p")
+ .RequireAttributeDescriptor(attribute => attribute.Name("class")))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("catchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("*")
+ .RequireAttributeDescriptor(attribute => attribute.Name("catchAll")))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, expectedErrors: new RazorDiagnostic[0]);
+ }
+
+ public static TheoryData MalformedRequiredAttributeData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<p",
+ new MarkupBlock(blockFactory.MarkupTagBlock("<p")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p class=\"btn\"",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p notRequired=\"hi\" class=\"btn\"",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("hi")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p></p",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<p>"),
+ blockFactory.MarkupTagBlock("</p")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p class=\"btn\"></p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p notRequired=\"hi\" class=\"btn\"></p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("hi")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(34, 0, 34), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p class=\"btn\" <p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: blockFactory.MarkupTagBlock("<p>"))),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ }
+ },
+ {
+ "<p notRequired=\"hi\" class=\"btn\" <p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("hi")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: blockFactory.MarkupTagBlock("<p>"))),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ }
+ },
+ {
+ "<p class=\"btn\" </p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(17, 0, 17), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p notRequired=\"hi\" class=\"btn\" </p",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "p",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("notRequired", factory.Markup("hi")),
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperMissingCloseAngle(
+ new SourceSpan(new SourceLocation(34, 0, 34), contentLength: 1), "p")
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(MalformedRequiredAttributeData))]
+ public void Rewrite_RequiredAttributeDescriptorsCreateMalformedTagHelperBlocksCorrectly(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ // Arrange
+ var descriptors = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("pTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("p")
+ .RequireAttributeDescriptor(attribute => attribute.Name("class")))
+ .Build(),
+ };
+
+ // Act & Assert
+ EvaluateData(descriptors, documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors);
+ }
+
+ public static TheoryData PrefixedTagHelperBoundData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ var availableDescriptorsColon = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("mythTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("myth"))
+ .Build(),
+ TagHelperDescriptorBuilder.Create("mythTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("myth2"))
+ .BoundAttributeDescriptor(attribute =>
+ attribute
+ .Name("bound")
+ .PropertyName("Bound")
+ .TypeName(typeof(bool).FullName))
+ .Build()
+ };
+ var availableDescriptorsCatchAll = new TagHelperDescriptor[]
+ {
+ TagHelperDescriptorBuilder.Create("mythTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("*"))
+ .Build(),
+ };
+
+ // documentContent, expectedOutput, availableDescriptors
+ return new TheoryData<string, MarkupBlock, IEnumerable<TagHelperDescriptor>>
+ {
+ {
+ "<th: />",
+ new MarkupBlock(blockFactory.MarkupTagBlock("<th: />")),
+ availableDescriptorsCatchAll
+ },
+ {
+ "<th:>words and spaces</th:>",
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("<th:>"),
+ factory.Markup("words and spaces"),
+ blockFactory.MarkupTagBlock("</th:>")),
+ availableDescriptorsCatchAll
+ },
+ {
+ "<th:myth />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("th:myth", tagMode: TagMode.SelfClosing)),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth></th:myth>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("th:myth")),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth><th:my2th></th:my2th></th:myth>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "th:myth",
+ blockFactory.MarkupTagBlock("<th:my2th>"),
+ blockFactory.MarkupTagBlock("</th:my2th>"))),
+ availableDescriptorsColon
+ },
+ {
+ "<!th:myth />",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "th:myth />")),
+ availableDescriptorsColon
+ },
+ {
+ "<!th:myth></!th:myth>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "th:myth>"),
+ blockFactory.EscapedMarkupTagBlock("</", "th:myth>")),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "th:myth",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth2 class=\"btn\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "th:myth2",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ })),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth class=\"btn\">words and spaces</th:myth>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "th:myth",
+ attributes: new List<TagHelperAttributeNode>
+ {
+ new TagHelperAttributeNode("class", factory.Markup("btn"))
+ },
+ children: factory.Markup("words and spaces"))),
+ availableDescriptorsColon
+ },
+ {
+ "<th:myth2 bound=\"@DateTime.Now\" />",
+ new MarkupBlock(
+ new MarkupTagHelperBlock(
+ "th:myth2",
+ tagMode: TagMode.SelfClosing,
+ attributes: new List<TagHelperAttributeNode>
+ {
+ {
+ new TagHelperAttributeNode(
+ "bound",
+ new MarkupBlock(
+ new MarkupBlock(
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
+ .Accepts(AcceptedCharactersInternal.AnyExceptNewline)))))
+ }
+ })),
+ availableDescriptorsColon
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(PrefixedTagHelperBoundData))]
+ public void Rewrite_AllowsPrefixedTagHelpers(
+ string documentContent,
+ object expectedOutput,
+ object availableDescriptors)
+ {
+ // Act & Assert
+ EvaluateData(
+ (IEnumerable<TagHelperDescriptor>)availableDescriptors,
+ documentContent,
+ (MarkupBlock)expectedOutput,
+ expectedErrors: Enumerable.Empty<RazorDiagnostic>(),
+ tagHelperPrefix: "th:");
+ }
+
+ public static TheoryData OptOut_WithAttributeTextTagData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!text class=\"btn\">}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>("\"", 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn", 16, 0, 16))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("}")))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 5), "!text"),
+ }
+ },
+ {
+ "@{<!text class=\"btn\"></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>("\"", 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn", 16, 0, 16))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!text class=\"btn\">words with spaces</!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>("\"", 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn", 16, 0, 16))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("words with spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!text class='btn1 btn2' class2=btn></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 8, 0, 8),
+ suffix: new LocationTagged<string>("'", 25, 0, 25)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn1", 16, 0, 16))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 20, 0, 20),
+ value: new LocationTagged<string>("btn2", 21, 0, 21))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class2",
+ prefix: new LocationTagged<string>(" class2=", 26, 0, 26),
+ suffix: new LocationTagged<string>(string.Empty, 37, 0, 37)),
+ factory.Markup(" class2=").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 34, 0, 34),
+ value: new LocationTagged<string>("btn", 34, 0, 34)))),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!text class='btn1 @DateTime.Now btn2'></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 8, 0, 8),
+ suffix: new LocationTagged<string>("'", 39, 0, 39)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn1", 16, 0, 16))),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(" ", 20, 0, 20), 21, 0, 21),
+ factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 34, 0, 34),
+ value: new LocationTagged<string>("btn2", 35, 0, 35))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ };
+ }
+ }
+
+ public static TheoryData OptOut_WithBlockTextTagData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ RazorDiagnostic MissingEndTagError(string tagName)
+ {
+ return RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: tagName.Length), tagName);
+ }
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!text>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ factory.Markup("}")))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ MissingEndTagError("!text"),
+ }
+ },
+ {
+ "@{</!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 4, lineIndex: 0, characterIndex: 4, length: 5), "!text"),
+ }
+ },
+ {
+ "@{<!text></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!text>words and spaces</!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ factory.Markup("words and spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!text></text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ blockFactory.MarkupTagBlock("</text>", AcceptedCharactersInternal.None))),
+ new []
+ {
+ MissingEndTagError("!text"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 11, lineIndex: 0, characterIndex: 11, length: 4), "text")
+ }
+ },
+ {
+ "@{<text></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(factory.MarkupTransition("<text>")),
+ new MarkupTagBlock(
+ factory.Markup("</").Accepts(AcceptedCharactersInternal.None),
+ factory.BangEscape(),
+ factory.Markup("text>").Accepts(AcceptedCharactersInternal.None)))),
+ new []
+ {
+ MissingEndTagError("text"),
+ }
+ },
+ {
+ "@{<!text><text></text></!text>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ new MarkupTagHelperBlock("text"),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<text><!text></!text>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(factory.MarkupTransition("<text>")),
+ new MarkupTagBlock(
+ factory.Markup("<").Accepts(AcceptedCharactersInternal.None),
+ factory.BangEscape(),
+ factory.Markup("text>").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None),
+ factory.Markup("}")))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ MissingEndTagError("text"),
+ }
+ },
+ {
+ "@{<!text></!text></text>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "text>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "text>", AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</text>", AcceptedCharactersInternal.None)),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml()),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 19, lineIndex: 0, characterIndex: 19, length: 4), "text"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 19, lineIndex: 0, characterIndex: 19, length: 4), "text")
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithAttributeTextTagData))]
+ [MemberData(nameof(OptOut_WithBlockTextTagData))]
+ public void Rewrite_AllowsTagHelperElementOptForCompleteTextTagInCSharpBlock(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "p", "text");
+ }
+
+ public static TheoryData OptOut_WithPartialTextTagData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ RazorDiagnostic UnfinishedTagError(string tagName, int length)
+ {
+ return RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(filePath: null, absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: length),
+ tagName);
+ }
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildPartialStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder()));
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!text}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(blockFactory.EscapedMarkupTagBlock("<", "text}"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text}", 6),
+ }
+ },
+ {
+ "@{<!text /}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock(
+ "<",
+ "text /",
+ new MarkupBlock(factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text", 5),
+ }
+ },
+ {
+ "@{<!text class=}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=", 8, 0, 8),
+ suffix: new LocationTagged<string>(string.Empty, 16, 0, 16)),
+ factory.Markup(" class=").With(SpanChunkGenerator.Null),
+ factory.Markup("}").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 15, 0, 15),
+ value: new LocationTagged<string>("}", 15, 0, 15))))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text", 5),
+ }
+ },
+ {
+ "@{<!text class=\"btn}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>(string.Empty, 20, 0, 20)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn}").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn}", 16, 0, 16))))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text", 5),
+ }
+ },
+ {
+ "@{<!text class=\"btn\"}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>("\"", 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn", 16, 0, 16))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text", 5),
+ }
+ },
+ {
+ "@{<!text class=\"btn\" /}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("text"),
+
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 8, 0, 8),
+ suffix: new LocationTagged<string>("\"", 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 16, 0, 16),
+ value: new LocationTagged<string>("btn", 16, 0, 16))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" /"),
+ new MarkupBlock(factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!text", 5),
+ }
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithPartialTextTagData))]
+ public void Rewrite_AllowsTagHelperElementOptForIncompleteTextTagInCSharpBlock(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "text");
+ }
+
+ public static TheoryData OptOut_WithPartialData_CSharp
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ RazorDiagnostic UnfinishedTagError(string tagName)
+ {
+ return RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
+ new SourceSpan(filePath: null, absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: tagName.Length),
+ tagName);
+ }
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildPartialStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder()));
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(blockFactory.EscapedMarkupTagBlock("<", "}"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!}"),
+ }
+ },
+ {
+ "@{<!p}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(blockFactory.EscapedMarkupTagBlock("<", "p}"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p}"),
+ }
+ },
+ {
+ "@{<!p /}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p /", new MarkupBlock(factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ },
+ {
+ "@{<!p class=}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=", 5, 0, 5),
+ suffix: new LocationTagged<string>(string.Empty, 13, 0, 13)),
+ factory.Markup(" class=").With(SpanChunkGenerator.Null),
+ factory.Markup("}").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 12, 0, 12),
+ value: new LocationTagged<string>("}", 12, 0, 12))))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ },
+ {
+ "@{<!p class=\"btn}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>(string.Empty, 17, 0, 17)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn}").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn}", 13, 0, 13))))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ },
+ {
+ "@{<!p class=\"btn@@}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>(string.Empty, 19, 0, 19)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ new MarkupBlock(
+ factory.Markup("@").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 16, 0, 16), new LocationTagged<string>("@", 16, 0, 16))).Accepts(AcceptedCharactersInternal.None),
+ factory.Markup("@").With(SpanChunkGenerator.Null).Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("}").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 18, 0, 18),
+ value: new LocationTagged<string>("}", 18, 0, 18))))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ },
+ {
+ "@{<!p class=\"btn\"}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>("\"", 16, 0, 16)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ },
+ {
+ "@{<!p class=\"btn\" /}",
+ buildPartialStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>("\"", 16, 0, 16)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" /"),
+ new MarkupBlock(
+ factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ UnfinishedTagError("!p"),
+ }
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithPartialData_CSharp))]
+ public void Rewrite_AllowsTagHelperElementOptForIncompleteHTMLInCSharpBlock(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+ public static TheoryData OptOut_WithPartialData_HTML
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput
+ return new TheoryData<string, MarkupBlock>
+ {
+ {
+ "<!",
+ new MarkupBlock(factory.Markup("<!"))
+ },
+ {
+ "<!p",
+ new MarkupBlock(blockFactory.EscapedMarkupTagBlock("<", "p"))
+ },
+ {
+ "<!p /",
+ new MarkupBlock(blockFactory.EscapedMarkupTagBlock("<", "p /"))
+ },
+ {
+ "<!p class=",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=", 3, 0, 3),
+ suffix: new LocationTagged<string>(string.Empty, 10, 0, 10)),
+ factory.Markup(" class=").With(SpanChunkGenerator.Null))))
+ },
+ {
+ "<!p class=\"btn",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>(string.Empty, 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))))))
+ },
+ {
+ "<!p class=\"btn\"",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>("\"", 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null))))
+ },
+ {
+ "<!p class=\"btn\" /",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>("\"", 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(" /")))
+ }
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithPartialData_HTML))]
+ public void Rewrite_AllowsTagHelperElementOptForIncompleteHTML(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, new RazorDiagnostic[0], "strong", "p");
+ }
+
+ public static TheoryData OptOut_WithBlockData_CSharp
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ RazorDiagnostic MissingEndTagError(string tagName, int index = 3)
+ {
+ return RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: index, lineIndex: 0, characterIndex: index, length: tagName.Length), tagName);
+ }
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ factory.Markup("}")))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ MissingEndTagError("!p"),
+ }
+ },
+ {
+ "@{</!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 4, lineIndex: 0, characterIndex: 4, length: 2), "!p"),
+ }
+ },
+ {
+ "@{<!p></!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!p>words and spaces</!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ factory.Markup("words and spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!p></p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None))),
+ new []
+ {
+ MissingEndTagError("!p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 8, lineIndex: 0, characterIndex: 8, length: 1), "p")
+ }
+ },
+ {
+ "@{<p></!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None)))),
+ new []
+ {
+ MissingEndTagError("p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 1), "p")
+ }
+ },
+ {
+ "@{<p><!p></!p></p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None)))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<p><!p></!p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None),
+ factory.Markup("}"))))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ MissingEndTagError("p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 1), "p")
+ }
+ },
+ {
+ "@{<!p></!p></p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</p>", AcceptedCharactersInternal.None)),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml()),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 13, lineIndex: 0, characterIndex: 13, length: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 13, lineIndex: 0, characterIndex: 13, length: 1), "p")
+ }
+ },
+ {
+ "@{<strong></!p></strong>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong",
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new MarkupBlock(
+ blockFactory.MarkupTagBlock("</strong>", AcceptedCharactersInternal.None)),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml()),
+ new []
+ {
+ MissingEndTagError("strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 17, lineIndex: 0, characterIndex: 17, length: 6), "strong")
+ }
+ },
+ {
+ "@{<strong></strong><!p></!p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong")),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None)),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml()),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<p><strong></!strong><!p></strong></!p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ blockFactory.EscapedMarkupTagBlock("</", "strong>", AcceptedCharactersInternal.None)))),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>", AcceptedCharactersInternal.None),
+ blockFactory.MarkupTagBlock("</strong>", AcceptedCharactersInternal.None)),
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None)),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml()),
+ new []
+ {
+ MissingEndTagError("p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 1), "p"),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 6, lineIndex: 0, characterIndex: 6, length: 6), "strong"),
+ MissingEndTagError("!p", index: 24),
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 29, lineIndex: 0, characterIndex: 29, length: 6), "strong"),
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 38, lineIndex: 0, characterIndex: 38, length: 2), "!p"),
+ }
+ },
+ };
+ }
+ }
+
+ public static TheoryData OptOut_WithAttributeData_CSharp
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ Func<Func<MarkupBlock>, MarkupBlock> buildStatementBlock = (insideBuilder) =>
+ {
+ return new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ insideBuilder(),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml());
+ };
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "@{<!p class=\"btn\">}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>("\"", 16, 0, 16)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("}")))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
+ RazorDiagnosticFactory.CreateParsing_MissingEndTag(
+ new SourceSpan(filePath: null, absoluteIndex: 3, lineIndex: 0, characterIndex: 3, length: 2), "!p"),
+ }
+ },
+ {
+ "@{<!p class=\"btn\"></!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>("\"", 16, 0, 16)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!p class=\"btn\">words with spaces</!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 5, 0, 5),
+ suffix: new LocationTagged<string>("\"", 16, 0, 16)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn", 13, 0, 13))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ factory.Markup("words with spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!p class='btn1 btn2' class2=btn></!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 5, 0, 5),
+ suffix: new LocationTagged<string>("'", 22, 0, 22)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn1", 13, 0, 13))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 17, 0, 17),
+ value: new LocationTagged<string>("btn2", 18, 0, 18))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class2",
+ prefix: new LocationTagged<string>(" class2=", 23, 0, 23),
+ suffix: new LocationTagged<string>(string.Empty, 34, 0, 34)),
+ factory.Markup(" class2=").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 31, 0, 31),
+ value: new LocationTagged<string>("btn", 31, 0, 31)))),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "@{<!p class='btn1 @DateTime.Now btn2'></!p>}",
+ buildStatementBlock(
+ () => new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 5, 0, 5),
+ suffix: new LocationTagged<string>("'", 36, 0, 36)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 13, 0, 13),
+ value: new LocationTagged<string>("btn1", 13, 0, 13))),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(" ", 17, 0, 17), 18, 0, 18),
+ factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 31, 0, 31),
+ value: new LocationTagged<string>("btn2", 32, 0, 32))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
+ blockFactory.EscapedMarkupTagBlock("</", "p>", AcceptedCharactersInternal.None))),
+ new RazorDiagnostic[0]
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithBlockData_CSharp))]
+ [MemberData(nameof(OptOut_WithAttributeData_CSharp))]
+ public void Rewrite_AllowsTagHelperElementOptOutCSharp(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+ public static TheoryData OptOut_WithBlockData_HTML
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<!p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "</!p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p></!p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p>words and spaces</!p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ factory.Markup("words and spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p></p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.MarkupTagBlock("</p>")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(absoluteIndex: 6, lineIndex: 0, characterIndex: 6, length: 1), "p")
+ }
+ },
+ {
+ "<p></!p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p", blockFactory.EscapedMarkupTagBlock("</", "p>"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<p><!p></!p></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>"))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p><!p></!p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ {
+ "<!p></!p></p>",
+ new MarkupBlock(
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>"),
+ blockFactory.MarkupTagBlock("</p>")),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(11, 0, 11), contentLength: 1), "p")
+ }
+ },
+ {
+ "<strong></!p></strong>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong",
+ blockFactory.EscapedMarkupTagBlock("</", "p>"))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<strong></strong><!p></!p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("strong"),
+ blockFactory.EscapedMarkupTagBlock("<", "p>"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<p><strong></!strong><!p></strong></!p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("strong",
+ blockFactory.EscapedMarkupTagBlock("</", "strong>"),
+ blockFactory.EscapedMarkupTagBlock("<", "p>")),
+ blockFactory.EscapedMarkupTagBlock("</", "p>"))),
+ new []
+ {
+ RazorDiagnosticFactory.CreateParsing_TagHelperFoundMalformedTagHelper(
+ new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), "p")
+ }
+ },
+ };
+ }
+ }
+
+ public static TheoryData OptOut_WithAttributeData_HTML
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ // documentContent, expectedOutput, expectedErrors
+ return new TheoryData<string, MarkupBlock, RazorDiagnostic[]>
+ {
+ {
+ "<!p class=\"btn\">",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>("\"", 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">"))),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p class=\"btn\"></!p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>("\"", 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p class=\"btn\">words and spaces</!p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class=\"", 3, 0, 3),
+ suffix: new LocationTagged<string>("\"", 14, 0, 14)),
+ factory.Markup(" class=\"").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn", 11, 0, 11))),
+ factory.Markup("\"").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ factory.Markup("words and spaces"),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p class='btn1 btn2' class2=btn></!p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 3, 0, 3),
+ suffix: new LocationTagged<string>("'", 20, 0, 20)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn1", 11, 0, 11))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 15, 0, 15),
+ value: new LocationTagged<string>("btn2", 16, 0, 16))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class2",
+ prefix: new LocationTagged<string>(" class2=", 21, 0, 21),
+ suffix: new LocationTagged<string>(string.Empty, 32, 0, 32)),
+ factory.Markup(" class2=").With(SpanChunkGenerator.Null),
+ factory.Markup("btn").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 29, 0, 29),
+ value: new LocationTagged<string>("btn", 29, 0, 29)))),
+ factory.Markup(">")),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ {
+ "<!p class='btn1 @DateTime.Now btn2'></!p>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<"),
+ factory.BangEscape(),
+ factory.Markup("p"),
+ new MarkupBlock(
+ new AttributeBlockChunkGenerator(
+ name: "class",
+ prefix: new LocationTagged<string>(" class='", 3, 0, 3),
+ suffix: new LocationTagged<string>("'", 34, 0, 34)),
+ factory.Markup(" class='").With(SpanChunkGenerator.Null),
+ factory.Markup("btn1").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(string.Empty, 11, 0, 11),
+ value: new LocationTagged<string>("btn1", 11, 0, 11))),
+ new MarkupBlock(
+ new DynamicAttributeBlockChunkGenerator(
+ new LocationTagged<string>(" ", 15, 0, 15), 16, 0, 16),
+ factory.Markup(" ").With(SpanChunkGenerator.Null),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("DateTime.Now")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace))),
+ factory.Markup(" btn2").With(
+ new LiteralAttributeChunkGenerator(
+ prefix: new LocationTagged<string>(" ", 29, 0, 29),
+ value: new LocationTagged<string>("btn2", 30, 0, 30))),
+ factory.Markup("'").With(SpanChunkGenerator.Null)),
+ factory.Markup(">")),
+ blockFactory.EscapedMarkupTagBlock("</", "p>")),
+ new RazorDiagnostic[0]
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(OptOut_WithBlockData_HTML))]
+ [MemberData(nameof(OptOut_WithAttributeData_HTML))]
+ public void Rewrite_AllowsTagHelperElementOptOutHTML(
+ string documentContent,
+ object expectedOutput,
+ object expectedErrors)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, (RazorDiagnostic[])expectedErrors, "strong", "p");
+ }
+
+ public static IEnumerable<object[]> TextTagsBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+
+ // Should re-write text tags that aren't in C# blocks
+ yield return new object[]
+ {
+ "<text>Hello World</text>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("text",
+ factory.Markup("Hello World")))
+ };
+ yield return new object[]
+ {
+ "@{<text>Hello World</text>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.MarkupTransition("<text>")),
+ factory.Markup("Hello World").Accepts(AcceptedCharactersInternal.None),
+ new MarkupTagBlock(
+ factory.MarkupTransition("</text>"))),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml())
+ };
+ yield return new object[]
+ {
+ "@{<text><p>Hello World</p></text>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.MarkupTransition("<text>")),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World")),
+ new MarkupTagBlock(
+ factory.MarkupTransition("</text>"))),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml())
+ };
+ yield return new object[]
+ {
+ "@{<p><text>Hello World</text></p>}",
+ new MarkupBlock(
+ factory.EmptyHtml(),
+ new StatementBlock(
+ factory.CodeTransition(),
+ factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("text",
+ factory.Markup("Hello World")))),
+ factory.EmptyCSharp().AsStatement(),
+ factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ factory.EmptyHtml())
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(TextTagsBlockData))]
+ public void TagHelperParseTreeRewriter_DoesNotRewriteTextTagTransitionTagHelpers(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p", "text");
+ }
+
+ public static IEnumerable<object[]> SpecialTagsBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+ yield return new object[]
+ {
+ "<foo><!-- Hello World --></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ blockFactory.HtmlCommentBlock (" Hello World "),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><!-- @foo --></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ BlockFactory.HtmlCommentBlock(factory, f=> new SyntaxTreeNode[]{
+ f.Markup(" ").Accepts(AcceptedCharactersInternal.WhiteSpace),
+ new ExpressionBlock(
+ f.CodeTransition(),
+ f.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" ").Accepts(AcceptedCharactersInternal.WhiteSpace) }),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><?xml Hello World ?></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<?xml Hello World ?>"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><?xml @foo ?></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<?xml "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" ?>"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><!DOCTYPE @foo ></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<!DOCTYPE "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" >"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><!DOCTYPE hello=\"world\" ></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<!DOCTYPE hello=\"world\" >"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><![CDATA[ Hello World ]]></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<![CDATA[ Hello World ]]>"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ yield return new object[]
+ {
+ "<foo><![CDATA[ @foo ]]></foo>",
+ new MarkupBlock(
+ new MarkupTagBlock(
+ factory.Markup("<foo>")),
+ factory.Markup("<![CDATA[ "),
+ new ExpressionBlock(
+ factory.CodeTransition(),
+ factory.Code("foo")
+ .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
+ .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
+ factory.Markup(" ]]>"),
+ new MarkupTagBlock(
+ factory.Markup("</foo>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(SpecialTagsBlockData))]
+ public void TagHelperParseTreeRewriter_DoesNotRewriteSpecialTagTagHelpers(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "!--", "?xml", "![CDATA[", "!DOCTYPE");
+ }
+
+ public static IEnumerable<object[]> NestedBlockData
+ {
+ get
+ {
+ var factory = new SpanFactory();
+ var blockFactory = new BlockFactory(factory);
+
+ yield return new object[]
+ {
+ "<p><div></div></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("div")))
+ };
+ yield return new object[]
+ {
+ "<p>Hello World <div></div></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hello World "),
+ new MarkupTagHelperBlock("div")))
+ };
+ yield return new object[]
+ {
+ "<p>Hel<p>lo</p></p> <p><div>World</div></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hel"),
+ new MarkupTagHelperBlock("p",
+ factory.Markup("lo"))),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ new MarkupTagHelperBlock("div",
+ factory.Markup("World"))))
+ };
+ yield return new object[]
+ {
+ "<p>Hel<strong>lo</strong></p> <p><span>World</span></p>",
+ new MarkupBlock(
+ new MarkupTagHelperBlock("p",
+ factory.Markup("Hel"),
+ blockFactory.MarkupTagBlock("<strong>"),
+ factory.Markup("lo"),
+ blockFactory.MarkupTagBlock("</strong>")),
+ factory.Markup(" "),
+ new MarkupTagHelperBlock("p",
+ blockFactory.MarkupTagBlock("<span>"),
+ factory.Markup("World"),
+ blockFactory.MarkupTagBlock("</span>")))
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(NestedBlockData))]
+ public void TagHelperParseTreeRewriter_RewritesNestedTagHelperTagBlocks(
+ string documentContent,
+ object expectedOutput)
+ {
+ RunParseTreeRewriterTest(documentContent, (MarkupBlock)expectedOutput, "p", "div");
+ }
+
+ [Fact]
+ public void Rewrite_HandlesMalformedNestedNonTagHelperTags_Correctly()
+ {
+ var documentContent = "<div>@{</div>}";
+ var expectedOutput = new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("<div>")),
+ new StatementBlock(
+ Factory.CodeTransition(),
+ Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
+ new MarkupBlock(
+ new MarkupTagBlock(
+ Factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None))),
+ Factory.EmptyCSharp().AsStatement(),
+ Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
+ Factory.EmptyHtml());
+ var expectedErrors = new[]
+ {
+ RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
+ new SourceSpan(new SourceLocation(9, 0, 9), contentLength: 3), "div"),
+ };
+
+ RunParseTreeRewriterTest(documentContent, expectedOutput, expectedErrors);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperRewritingTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperRewritingTestBase.cs
new file mode 100644
index 0000000000..8271cee1a9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TagHelperRewritingTestBase.cs
@@ -0,0 +1,75 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TagHelperRewritingTestBase : CsHtmlMarkupParserTestBase
+ {
+ internal void RunParseTreeRewriterTest(
+ string documentContent,
+ MarkupBlock expectedOutput,
+ params string[] tagNames)
+ {
+ RunParseTreeRewriterTest(
+ documentContent,
+ expectedOutput,
+ errors: Enumerable.Empty<RazorDiagnostic>(),
+ tagNames: tagNames);
+ }
+
+ internal void RunParseTreeRewriterTest(
+ string documentContent,
+ MarkupBlock expectedOutput,
+ IEnumerable<RazorDiagnostic> errors,
+ params string[] tagNames)
+ {
+ var descriptors = BuildDescriptors(tagNames);
+
+ EvaluateData(descriptors, documentContent, expectedOutput, errors);
+ }
+
+ internal IEnumerable<TagHelperDescriptor> BuildDescriptors(params string[] tagNames)
+ {
+ var descriptors = new List<TagHelperDescriptor>();
+
+ foreach (var tagName in tagNames)
+ {
+ var descriptor = TagHelperDescriptorBuilder.Create(tagName + "taghelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName(tagName))
+ .Build();
+ descriptors.Add(descriptor);
+ }
+
+ return descriptors;
+ }
+
+ internal void EvaluateData(
+ IEnumerable<TagHelperDescriptor> descriptors,
+ string documentContent,
+ MarkupBlock expectedOutput,
+ IEnumerable<RazorDiagnostic> expectedErrors,
+ string tagHelperPrefix = null,
+ RazorParserFeatureFlags featureFlags = null)
+ {
+ var syntaxTree = ParseDocument(documentContent);
+ var errorSink = new ErrorSink();
+ var parseTreeRewriter = new TagHelperParseTreeRewriter(
+ tagHelperPrefix,
+ descriptors,
+ featureFlags ?? syntaxTree.Options.FeatureFlags);
+
+ var actualTree = parseTreeRewriter.Rewrite(syntaxTree.Root, errorSink);
+
+ var allErrors = syntaxTree.Diagnostics.Concat(errorSink.Errors);
+ var actualErrors = allErrors
+ .OrderBy(error => error.Span.AbsoluteIndex)
+ .ToList();
+
+ EvaluateRazorErrors(actualErrors, expectedErrors.ToList());
+ EvaluateParseTree(actualTree, expectedOutput);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TextReaderExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TextReaderExtensionsTest.cs
new file mode 100644
index 0000000000..e95878c148
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TextReaderExtensionsTest.cs
@@ -0,0 +1,113 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TextReaderExtensionsTest
+ {
+ [Fact]
+ public void ReadUntilWithCharReadsAllTextUpToSpecifiedCharacterButNotPast()
+ {
+ RunReaderTest("foo bar baz @biz", "foo bar baz ", '@', r => r.ReadUntil('@'));
+ }
+
+ [Fact]
+ public void ReadUntilWithCharWithInclusiveFlagReadsAllTextUpToSpecifiedCharacterButNotPastIfInclusiveFalse()
+ {
+ RunReaderTest("foo bar baz @biz", "foo bar baz ", '@', r => r.ReadUntil('@', inclusive: false));
+ }
+
+ [Fact]
+ public void ReadUntilWithCharWithInclusiveFlagReadsAllTextUpToAndIncludingSpecifiedCharacterIfInclusiveTrue()
+ {
+ RunReaderTest("foo bar baz @biz", "foo bar baz @", 'b', r => r.ReadUntil('@', inclusive: true));
+ }
+
+ [Fact]
+ public void ReadUntilWithCharReadsToEndIfSpecifiedCharacterNotFound()
+ {
+ RunReaderTest("foo bar baz", "foo bar baz", -1, r => r.ReadUntil('@'));
+ }
+
+ [Fact]
+ public void ReadUntilWithMultipleTerminatorsReadsUntilAnyTerminatorIsFound()
+ {
+ RunReaderTest("<bar/>", "<bar", '/', r => r.ReadUntil('/', '>'));
+ }
+
+ [Fact]
+ public void ReadUntilWithMultipleTerminatorsHonorsInclusiveFlagWhenFalse()
+ {
+ // NOTE: Using named parameters would be difficult here, hence the inline comment
+ RunReaderTest("<bar/>", "<bar", '/', r => r.ReadUntil(/* inclusive */ false, '/', '>'));
+ }
+
+ [Fact]
+ public void ReadUntilWithMultipleTerminatorsHonorsInclusiveFlagWhenTrue()
+ {
+ // NOTE: Using named parameters would be difficult here, hence the inline comment
+ RunReaderTest("<bar/>", "<bar/", '>', r => r.ReadUntil(/* inclusive */ true, '/', '>'));
+ }
+
+ [Fact]
+ public void ReadUntilWithPredicateStopsWhenPredicateIsTrue()
+ {
+ RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz ", '0', r => r.ReadUntil(c => Char.IsDigit(c)));
+ }
+
+ [Fact]
+ public void ReadUntilWithPredicateHonorsInclusiveFlagWhenFalse()
+ {
+ RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz ", '0', r => r.ReadUntil(c => Char.IsDigit(c), inclusive: false));
+ }
+
+ [Fact]
+ public void ReadUntilWithPredicateHonorsInclusiveFlagWhenTrue()
+ {
+ RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz 0", ' ', r => r.ReadUntil(c => Char.IsDigit(c), inclusive: true));
+ }
+
+ [Fact]
+ public void ReadWhileWithPredicateStopsWhenPredicateIsFalse()
+ {
+ RunReaderTest("012345a67890", "012345", 'a', r => r.ReadWhile(c => Char.IsDigit(c)));
+ }
+
+ [Fact]
+ public void ReadWhileWithPredicateHonorsInclusiveFlagWhenFalse()
+ {
+ RunReaderTest("012345a67890", "012345", 'a', r => r.ReadWhile(c => Char.IsDigit(c), inclusive: false));
+ }
+
+ [Fact]
+ public void ReadWhileWithPredicateHonorsInclusiveFlagWhenTrue()
+ {
+ RunReaderTest("012345a67890", "012345a", '6', r => r.ReadWhile(c => Char.IsDigit(c), inclusive: true));
+ }
+
+ private static void RunReaderTest(string testString, string expectedOutput, int expectedPeek, Func<TextReader, string> action)
+ {
+ // Arrange
+ var reader = new StringReader(testString);
+
+ // Act
+ var read = action(reader);
+
+ // Assert
+ Assert.Equal(expectedOutput, read);
+
+ if (expectedPeek == -1)
+ {
+ Assert.True(reader.Peek() == -1, "Expected that the reader would be positioned at the end of the input stream");
+ }
+ else
+ {
+ Assert.Equal((char)expectedPeek, (char)reader.Peek());
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerLookaheadTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerLookaheadTest.cs
new file mode 100644
index 0000000000..aa9ea560cc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerLookaheadTest.cs
@@ -0,0 +1,221 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class TokenizerLookaheadTest : HtmlTokenizerTestBase
+ {
+ [Fact]
+ public void Lookahead_MaintainsExistingBufferWhenRejected()
+ {
+ // Arrange
+ var tokenizer = new ExposedTokenizer("01234");
+ tokenizer.Buffer.Append("pre-existing values");
+
+ // Act
+ var result = tokenizer.Lookahead("0x", takeIfMatch: true, caseSensitive: true);
+
+ // Assert
+ Assert.False(result);
+ Assert.Equal("pre-existing values", tokenizer.Buffer.ToString(), StringComparer.Ordinal);
+ }
+
+ [Fact]
+ public void Lookahead_AddsToExistingBufferWhenSuccessfulAndTakeIfMatchIsTrue()
+ {
+ // Arrange
+ var tokenizer = new ExposedTokenizer("0x1234");
+ tokenizer.Buffer.Append("pre-existing values");
+
+ // Act
+ var result = tokenizer.Lookahead("0x", takeIfMatch: true, caseSensitive: true);
+
+ // Assert
+ Assert.True(result);
+ Assert.Equal("pre-existing values0x", tokenizer.Buffer.ToString(), StringComparer.Ordinal);
+ }
+
+ [Fact]
+ public void Lookahead_MaintainsExistingBufferWhenSuccessfulAndTakeIfMatchIsFalse()
+ {
+ // Arrange
+ var tokenizer = new ExposedTokenizer("0x1234");
+ tokenizer.Buffer.Append("pre-existing values");
+
+ // Act
+ var result = tokenizer.Lookahead("0x", takeIfMatch: false, caseSensitive: true);
+
+ // Assert
+ Assert.True(result);
+ Assert.Equal("pre-existing values", tokenizer.Buffer.ToString(), StringComparer.Ordinal);
+ }
+
+ [Fact]
+ public void LookaheadUntil_PassesThePreviousSymbolsInTheSameOrder()
+ {
+ // Arrange
+ var tokenizer = CreateContentTokenizer("asdf--fvd--<");
+
+ // Act
+ var i = 3;
+ IEnumerable<HtmlSymbol> previousSymbols = null;
+ var symbolFound = tokenizer.LookaheadUntil((s, p) =>
+ {
+ previousSymbols = p;
+ return --i == 0;
+ });
+
+ // Assert
+ Assert.Equal(4, previousSymbols.Count());
+
+ // For the very first element, there will be no previous items, so null is expected
+ var orderIndex = 0;
+ Assert.Null(previousSymbols.ElementAt(orderIndex++));
+ Assert.Equal(new HtmlSymbol("asdf", HtmlSymbolType.Text), previousSymbols.ElementAt(orderIndex++));
+ Assert.Equal(new HtmlSymbol("--", HtmlSymbolType.DoubleHyphen), previousSymbols.ElementAt(orderIndex++));
+ Assert.Equal(new HtmlSymbol("fvd", HtmlSymbolType.Text), previousSymbols.ElementAt(orderIndex++));
+ }
+
+ [Fact]
+ public void LookaheadUntil_ReturnsFalseAfterIteratingOverAllSymbolsIfConditionIsNotMet()
+ {
+ // Arrange
+ var tokenizer = CreateContentTokenizer("asdf--fvd");
+
+ // Act
+ var symbols = new Stack<HtmlSymbol>();
+ var symbolFound = tokenizer.LookaheadUntil((s, p) =>
+ {
+ symbols.Push(s);
+ return false;
+ });
+
+ // Assert
+ Assert.False(symbolFound);
+ Assert.Equal(3, symbols.Count);
+ Assert.Equal(new HtmlSymbol("fvd", HtmlSymbolType.Text), symbols.Pop());
+ Assert.Equal(new HtmlSymbol("--", HtmlSymbolType.DoubleHyphen), symbols.Pop());
+ Assert.Equal(new HtmlSymbol("asdf", HtmlSymbolType.Text), symbols.Pop());
+ }
+
+ [Fact]
+ public void LookaheadUntil_ReturnsTrueAndBreaksIteration()
+ {
+ // Arrange
+ var tokenizer = CreateContentTokenizer("asdf--fvd");
+
+ // Act
+ var symbols = new Stack<HtmlSymbol>();
+ var symbolFound = tokenizer.LookaheadUntil((s, p) =>
+ {
+ symbols.Push(s);
+ return s.Type == HtmlSymbolType.DoubleHyphen;
+ });
+
+ // Assert
+ Assert.True(symbolFound);
+ Assert.Equal(2, symbols.Count);
+ Assert.Equal(new HtmlSymbol("--", HtmlSymbolType.DoubleHyphen), symbols.Pop());
+ Assert.Equal(new HtmlSymbol("asdf", HtmlSymbolType.Text), symbols.Pop());
+ }
+
+ private static TestTokenizerBackedParser CreateContentTokenizer(string content)
+ {
+ var source = TestRazorSourceDocument.Create(content);
+ var options = RazorParserOptions.CreateDefault();
+ var context = new ParserContext(source, options);
+
+ var tokenizer = new TestTokenizerBackedParser(HtmlLanguageCharacteristics.Instance, context);
+ return tokenizer;
+ }
+
+ private class ExposedTokenizer : Tokenizer<CSharpSymbol, CSharpSymbolType>
+ {
+ public ExposedTokenizer(string input)
+ : base(new SeekableTextReader(input, filePath: null))
+ {
+ }
+
+ public new StringBuilder Buffer
+ {
+ get
+ {
+ return base.Buffer;
+ }
+ }
+
+ public override CSharpSymbolType RazorCommentStarType
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public override CSharpSymbolType RazorCommentTransitionType
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ public override CSharpSymbolType RazorCommentType
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ protected override int StartState
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ protected override CSharpSymbol CreateSymbol(
+ string content,
+ CSharpSymbolType type,
+ IReadOnlyList<RazorDiagnostic> errors)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override StateResult Dispatch()
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private class TestTokenizerBackedParser : TokenizerBackedParser<HtmlTokenizer, HtmlSymbol, HtmlSymbolType>
+ {
+ internal TestTokenizerBackedParser(LanguageCharacteristics<HtmlTokenizer, HtmlSymbol, HtmlSymbolType> language, ParserContext context) : base(language, context)
+ {
+ }
+
+ public override void ParseBlock()
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override bool SymbolTypeEquals(HtmlSymbolType x, HtmlSymbolType y)
+ {
+ throw new NotImplementedException();
+ }
+
+ internal new bool LookaheadUntil(Func<HtmlSymbol, IEnumerable<HtmlSymbol>, bool> condition)
+ {
+ return base.LookaheadUntil(condition);
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerTestBase.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerTestBase.cs
new file mode 100644
index 0000000000..bcd2eff90b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TokenizerTestBase.cs
@@ -0,0 +1,72 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// 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.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public abstract class TokenizerTestBase
+ {
+ internal abstract object IgnoreRemaining { get; }
+ internal abstract object CreateTokenizer(ITextDocument source);
+
+ internal void TestTokenizer<TSymbol, TSymbolType>(string input, params TSymbol[] expectedSymbols)
+ where TSymbolType : struct
+ where TSymbol : SymbolBase<TSymbolType>
+ {
+ // Arrange
+ var success = true;
+ var output = new StringBuilder();
+ using (var source = new SeekableTextReader(input, filePath: null))
+ {
+ var tokenizer = (Tokenizer<TSymbol, TSymbolType>)CreateTokenizer(source);
+ var counter = 0;
+ TSymbol current = null;
+ while ((current = tokenizer.NextSymbol()) != null)
+ {
+ if (counter >= expectedSymbols.Length)
+ {
+ output.AppendLine(string.Format("F: Expected: << Nothing >>; Actual: {0}", current));
+ success = false;
+ }
+ else if (ReferenceEquals(expectedSymbols[counter], IgnoreRemaining))
+ {
+ output.AppendLine(string.Format("P: Ignored {0}", current));
+ }
+ else
+ {
+ if (!Equals(expectedSymbols[counter], current))
+ {
+ output.AppendLine(string.Format("F: Expected: {0}; Actual: {1}", expectedSymbols[counter], current));
+ success = false;
+ }
+ else
+ {
+ output.AppendLine(string.Format("P: Expected: {0}", expectedSymbols[counter]));
+ }
+ counter++;
+ }
+ }
+ if (counter < expectedSymbols.Length && !ReferenceEquals(expectedSymbols[counter], IgnoreRemaining))
+ {
+ success = false;
+ for (; counter < expectedSymbols.Length; counter++)
+ {
+ output.AppendLine(string.Format("F: Expected: {0}; Actual: << None >>", expectedSymbols[counter]));
+ }
+ }
+ }
+ Assert.True(success, Environment.NewLine + output.ToString());
+ WriteTraceLine(output.Replace("{", "{{").Replace("}", "}}").ToString());
+ }
+
+ [Conditional("PARSER_TRACE")]
+ private static void WriteTraceLine(string format, params object[] args)
+ {
+ Trace.WriteLine(string.Format(format, args));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/WhiteSpaceRewriterTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/WhiteSpaceRewriterTest.cs
new file mode 100644
index 0000000000..96531135c3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/WhiteSpaceRewriterTest.cs
@@ -0,0 +1,40 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Legacy
+{
+ public class WhiteSpaceRewriterTest
+ {
+ [Fact]
+ public void Rewrite_Moves_Whitespace_Preceeding_ExpressionBlock_To_Parent_Block()
+ {
+ // Arrange
+ var factory = new SpanFactory();
+ var start = new MarkupBlock(
+ factory.Markup("test"),
+ new ExpressionBlock(
+ factory.Code(" ").AsExpression(),
+ factory.CodeTransition(SyntaxConstants.TransitionString),
+ factory.Code("foo").AsExpression()),
+ factory.Markup("test"));
+ var rewriter = new WhiteSpaceRewriter();
+
+ // Act
+ var rewritten = rewriter.Rewrite(start);
+ factory.Reset();
+
+ // Assert
+ ParserTestBase.EvaluateParseTree(
+ rewritten,
+ new MarkupBlock(
+ factory.Markup("test"),
+ factory.Markup(" "),
+ new ExpressionBlock(
+ factory.CodeTransition(SyntaxConstants.TransitionString),
+ factory.Code("foo").AsExpression()),
+ factory.Markup("test")));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Microsoft.AspNetCore.Razor.Language.Test.csproj b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Microsoft.AspNetCore.Razor.Language.Test.csproj
new file mode 100644
index 0000000000..68d1243acf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Microsoft.AspNetCore.Razor.Language.Test.csproj
@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFrameworks>$(DeveloperBuildTestTfms)</TargetFrameworks>
+ <TargetFrameworks Condition=" '$(DeveloperBuild)' != 'true' ">$(TargetFrameworks)</TargetFrameworks>
+ <TargetFrameworks Condition=" '$(DeveloperBuild)' != 'true' AND '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net46</TargetFrameworks>
+ <DefaultItemExcludes>$(DefaultItemExcludes);TestFiles\**\*</DefaultItemExcludes>
+ <DefineConstants Condition="'$(GenerateBaselines)'=='true'">$(DefineConstants);GENERATE_BASELINES</DefineConstants>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <EmbeddedResource Include="TestFiles\**\*" />
+ <None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Microsoft.AspNetCore.Razor.Language\Microsoft.AspNetCore.Razor.Language.csproj" />
+ <ProjectReference Include="..\Microsoft.AspNetCore.Razor.Test.Common\Microsoft.AspNetCore.Razor.Test.Common.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore.Testing" Version="$(MicrosoftAspNetCoreTestingPackageVersion)" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
+ <PackageReference Include="Moq" Version="$(MoqPackageVersion)" />
+ <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonPackageVersion)" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualStudioPackageVersion)" />
+ <PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Properties/AssemblyInfo.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..3337ebeac2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,6 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentExtensionsTest.cs
new file mode 100644
index 0000000000..41f899512b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentExtensionsTest.cs
@@ -0,0 +1,214 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Intermediate;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorCodeDocumentExtensionsTest
+ {
+ [Fact]
+ public void GetRazorSyntaxTree_ReturnsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorSyntaxTree.Parse(codeDocument.Source);
+ codeDocument.Items[typeof(RazorSyntaxTree)] = expected;
+
+ // Act
+ var actual = codeDocument.GetSyntaxTree();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetRazorSyntaxTree_SetsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorSyntaxTree.Parse(codeDocument.Source);
+
+ // Act
+ codeDocument.SetSyntaxTree(expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(RazorSyntaxTree)]);
+ }
+
+ [Fact]
+ public void GetAndSetImportSyntaxTrees_ReturnsSyntaxTrees()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = new[] { RazorSyntaxTree.Parse(codeDocument.Source), };
+ codeDocument.SetImportSyntaxTrees(expected);
+
+ // Act
+ var actual = codeDocument.GetImportSyntaxTrees();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void GetIRDocument_ReturnsIRDocument()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = new DocumentIntermediateNode();
+ codeDocument.Items[typeof(DocumentIntermediateNode)] = expected;
+
+ // Act
+ var actual = codeDocument.GetDocumentIntermediateNode();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetIRDocument_SetsIRDocument()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = new DocumentIntermediateNode();
+
+ // Act
+ codeDocument.SetDocumentIntermediateNode((DocumentIntermediateNode)expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(DocumentIntermediateNode)]);
+ }
+
+ [Fact]
+ public void GetCSharpDocument_ReturnsCSharpDocument()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorCSharpDocument.Create("", RazorCodeGenerationOptions.CreateDefault(), Array.Empty<RazorDiagnostic>());
+ codeDocument.Items[typeof(RazorCSharpDocument)] = expected;
+
+ // Act
+ var actual = codeDocument.GetCSharpDocument();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetCSharpDocument_SetsCSharpDocument()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorCSharpDocument.Create("", RazorCodeGenerationOptions.CreateDefault(), Array.Empty<RazorDiagnostic>());
+
+ // Act
+ codeDocument.SetCSharpDocument(expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(RazorCSharpDocument)]);
+ }
+
+ [Fact]
+ public void GetTagHelperContext_ReturnsTagHelperContext()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = TagHelperDocumentContext.Create(null, new TagHelperDescriptor[0]);
+ codeDocument.Items[typeof(TagHelperDocumentContext)] = expected;
+
+ // Act
+ var actual = codeDocument.GetTagHelperContext();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetTagHelperContext_SetsTagHelperContext()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = TagHelperDocumentContext.Create(null, new TagHelperDescriptor[0]);
+
+ // Act
+ codeDocument.SetTagHelperContext(expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(TagHelperDocumentContext)]);
+ }
+
+ [Fact]
+ public void GetParserOptions_ReturnsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorParserOptions.CreateDefault();
+ codeDocument.Items[typeof(RazorParserOptions)] = expected;
+
+ // Act
+ var actual = codeDocument.GetParserOptions();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetParserOptions_SetsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorParserOptions.CreateDefault();
+
+ // Act
+ codeDocument.SetParserOptions(expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(RazorParserOptions)]);
+ }
+
+ [Fact]
+ public void GetCodeGenerationOptions_ReturnsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorCodeGenerationOptions.CreateDefault();
+ codeDocument.Items[typeof(RazorCodeGenerationOptions)] = expected;
+
+ // Act
+ var actual = codeDocument.GetCodeGenerationOptions();
+
+ // Assert
+ Assert.Same(expected, actual);
+ }
+
+ [Fact]
+ public void SetCodeGenerationOptions_SetsSyntaxTree()
+ {
+ // Arrange
+ var codeDocument = TestRazorCodeDocument.CreateEmpty();
+
+ var expected = RazorCodeGenerationOptions.CreateDefault();
+
+ // Act
+ codeDocument.SetCodeGenerationOptions(expected);
+
+ // Assert
+ Assert.Same(expected, codeDocument.Items[typeof(RazorCodeGenerationOptions)]);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentTest.cs
new file mode 100644
index 0000000000..c0cce4b7c6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorCodeDocumentTest.cs
@@ -0,0 +1,61 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorCodeDocumentTest
+ {
+ [Fact]
+ public void Create()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+
+ // Act
+ var code = RazorCodeDocument.Create(source);
+
+ // Assert
+ Assert.Same(source, code.Source);
+ Assert.NotNull(code.Items);
+ }
+
+ [Fact]
+ public void Create_WithImports()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+
+ var imports = new RazorSourceDocument[]
+ {
+ TestRazorSourceDocument.Create(),
+ };
+
+ // Act
+ var code = RazorCodeDocument.Create(source, imports);
+
+ // Assert
+ Assert.Same(source, code.Source);
+ Assert.NotNull(code.Items);
+
+ Assert.NotSame(imports, code.Imports);
+ Assert.Collection(imports, d => Assert.Same(imports[0], d));
+ }
+
+ [Fact]
+ public void Create_WithImports_AllowsNull()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create();
+
+ // Act
+ var code = RazorCodeDocument.Create(source, imports: null);
+
+ // Assert
+ Assert.Same(source, code.Source);
+ Assert.NotNull(code.Items);
+ Assert.Empty(code.Imports);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticDescriptorTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticDescriptorTest.cs
new file mode 100644
index 0000000000..9b3af87f6f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticDescriptorTest.cs
@@ -0,0 +1,78 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorDiagnosticDescriptorTest
+ {
+ [Fact]
+ public void RazorDiagnosticDescriptor_Ctor()
+ {
+ // Arrange & Act
+ var descriptor = new RazorDiagnosticDescriptor("RZ0001", () => "Hello, World!", RazorDiagnosticSeverity.Error);
+
+ // Assert
+ Assert.Equal("RZ0001", descriptor.Id);
+ Assert.Equal(RazorDiagnosticSeverity.Error, descriptor.Severity);
+ Assert.Equal("Hello, World!", descriptor.GetMessageFormat());
+ }
+
+ [Fact]
+ public void RazorDiagnosticDescriptor_Equals()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "a!", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0001", () => "b!", RazorDiagnosticSeverity.Error);
+
+ // Act
+ var result = descriptor1.Equals(descriptor2);
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void RazorDiagnosticDescriptor_NotEquals()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "a!", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0002", () => "b!", RazorDiagnosticSeverity.Error);
+
+ // Act
+ var result = descriptor1.Equals(descriptor2);
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void RazorDiagnosticDescriptor_HashCodesEqual()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "a!", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0001", () => "b!", RazorDiagnosticSeverity.Error);
+
+ // Act
+ var result = descriptor1.GetHashCode() == descriptor2.GetHashCode();
+
+ // Assert
+ Assert.True(result);
+ }
+
+ [Fact]
+ public void RazorDiagnosticDescriptor_HashCodesNotEqual()
+ {
+ // Arrange
+ var descriptor1 = new RazorDiagnosticDescriptor("RZ0001", () => "a!", RazorDiagnosticSeverity.Error);
+ var descriptor2 = new RazorDiagnosticDescriptor("RZ0002", () => "b!", RazorDiagnosticSeverity.Error);
+
+ // Act
+ var result = descriptor1.GetHashCode() == descriptor2.GetHashCode();
+
+ // Assert
+ Assert.False(result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticTest.cs
new file mode 100644
index 0000000000..0ad45e8ed5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorDiagnosticTest.cs
@@ -0,0 +1,45 @@
+// Copyright(c) .NET Foundation.All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorDiagnosticTest
+ {
+ [Fact]
+ public void Create_WithDescriptor_CreatesDefaultRazorDiagnostic()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0001", () => "a", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ // Act
+ var diagnostic = RazorDiagnostic.Create(descriptor, span);
+
+ // Assert
+ var defaultDiagnostic = Assert.IsType<DefaultRazorDiagnostic>(diagnostic);
+ Assert.Equal("RZ0001", defaultDiagnostic.Id);
+ Assert.Equal(RazorDiagnosticSeverity.Error, defaultDiagnostic.Severity);
+ Assert.Equal(span, diagnostic.Span);
+ }
+
+ [Fact]
+ public void Create_WithDescriptor_AndArgs_CreatesDefaultRazorDiagnostic()
+ {
+ // Arrange
+ var descriptor = new RazorDiagnosticDescriptor("RZ0001", () => "a", RazorDiagnosticSeverity.Error);
+ var span = new SourceSpan("test.cs", 15, 1, 8, 5);
+
+ // Act
+ var diagnostic = RazorDiagnostic.Create(descriptor, span, "Hello", "World");
+
+ // Assert
+ var defaultDiagnostic = Assert.IsType<DefaultRazorDiagnostic>(diagnostic);
+ Assert.Equal("RZ0001", defaultDiagnostic.Id);
+ Assert.Equal(RazorDiagnosticSeverity.Error, defaultDiagnostic.Severity);
+ Assert.Equal(span, diagnostic.Span);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineBuilderExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineBuilderExtensionsTest.cs
new file mode 100644
index 0000000000..3df637cadc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineBuilderExtensionsTest.cs
@@ -0,0 +1,98 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+#pragma warning disable CS0618 // Type or member is obsolete
+ public class RazorEngineBuilderExtensionsTest
+ {
+ [Fact]
+ public void AddDirective_ExistingFeature_UsesFeature()
+ {
+ // Arrange
+ var expected = new DefaultRazorDirectiveFeature();
+ var engine = RazorEngine.CreateEmpty(b =>
+ {
+ b.Features.Add(expected);
+
+ // Act
+ b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
+ });
+
+ // Assert
+ var actual = Assert.Single(engine.Features.OfType<IRazorDirectiveFeature>());
+ Assert.Same(expected, actual);
+
+ var directive = Assert.Single(actual.Directives);
+ Assert.Equal("test", directive.Directive);
+ }
+
+ [Fact]
+ public void AddDirective_NoFeature_CreatesFeature()
+ {
+ // Arrange
+ var engine = RazorEngine.CreateEmpty(b =>
+ {
+ // Act
+ b.AddDirective(DirectiveDescriptor.CreateDirective("test", DirectiveKind.SingleLine));
+ });
+
+ // Assert
+ var actual = Assert.Single(engine.Features.OfType<IRazorDirectiveFeature>());
+ Assert.IsType<DefaultRazorDirectiveFeature>(actual);
+
+ var directive = Assert.Single(actual.Directives);
+ Assert.Equal("test", directive.Directive);
+ }
+
+ [Fact]
+ public void AddTargetExtensions_ExistingFeature_UsesFeature()
+ {
+ // Arrange
+ var extension = new MyTargetExtension();
+
+ var expected = new DefaultRazorTargetExtensionFeature();
+ var engine = RazorEngine.CreateEmpty(b =>
+ {
+ b.Features.Add(expected);
+
+ // Act
+ b.AddTargetExtension(extension);
+ });
+
+ // Assert
+ var actual = Assert.Single(engine.Features.OfType<IRazorTargetExtensionFeature>());
+ Assert.Same(expected, actual);
+
+ Assert.Same(extension, Assert.Single(actual.TargetExtensions));
+ }
+
+ [Fact]
+ public void AddTargetExtensions_NoFeature_CreatesFeature()
+ {
+ // Arrange
+ var extension = new MyTargetExtension();
+
+ var engine = RazorEngine.CreateEmpty(b =>
+ {
+ // Act
+ b.AddTargetExtension(extension);
+ });
+
+ // Assert
+ var actual = Assert.Single(engine.Features.OfType<IRazorTargetExtensionFeature>());
+ Assert.IsType<DefaultRazorTargetExtensionFeature>(actual);
+
+ Assert.Same(extension, Assert.Single(actual.TargetExtensions));
+ }
+
+ private class MyTargetExtension : ICodeTargetExtension
+ {
+ }
+ }
+#pragma warning restore CS0618 // Type or member is obsolete
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs
new file mode 100644
index 0000000000..225f73f342
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorEngineTest.cs
@@ -0,0 +1,233 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+#pragma warning disable CS0618 // Type or member is obsolete
+ public class RazorEngineTest
+ {
+ [Fact]
+ public void Create_NoArg_CreatesDefaultRuntimeEngine()
+ {
+ // Arrange
+ // Act
+ var engine = RazorEngine.Create();
+
+ // Assert
+ Assert.IsType<DefaultRazorEngine>(engine);
+ AssertDefaultRuntimeFeatures(engine.Features);
+ AssertDefaultRuntimePhases(engine.Phases);
+ AssertDefaultRuntimeTargetExtensions(engine);
+ }
+
+ [Fact]
+ public void CreateDesignTime_NoArg_CreatesDefaultDesignTimeEngine()
+ {
+ // Arrange
+ // Act
+ var engine = RazorEngine.CreateDesignTime();
+
+ // Assert
+ Assert.IsType<DefaultRazorEngine>(engine);
+ AssertDefaultDesignTimeFeatures(engine.Features);
+ AssertDefaultDesignTimePhases(engine.Phases);
+ AssertDefaultDesignTimeTargetExtensions(engine);
+ }
+
+ [Fact]
+ public void Create_Null_CreatesDefaultRuntimeEngine()
+ {
+ // Arrange
+ // Act
+ var engine = RazorEngine.Create(configure: null);
+
+ // Assert
+ Assert.IsType<DefaultRazorEngine>(engine);
+ AssertDefaultRuntimeFeatures(engine.Features);
+ AssertDefaultRuntimePhases(engine.Phases);
+ AssertDefaultRuntimeTargetExtensions(engine);
+ }
+
+ [Fact]
+ public void CreateDesignTime_Null_CreatesDefaultDesignTimeEngine()
+ {
+ // Arrange
+ // Act
+ var engine = RazorEngine.CreateDesignTime(configure: null);
+
+ // Assert
+ Assert.IsType<DefaultRazorEngine>(engine);
+ AssertDefaultDesignTimeFeatures(engine.Features);
+ AssertDefaultDesignTimePhases(engine.Phases);
+ AssertDefaultDesignTimeTargetExtensions(engine);
+ }
+
+ [Fact]
+ public void Create_Lambda_AddsFeaturesAndPhases()
+ {
+ // Arrange
+ IRazorEngineFeature[] features = null;
+ IRazorEnginePhase[] phases = null;
+
+ // Act
+ var engine = RazorEngine.Create(builder =>
+ {
+ builder.Features.Clear();
+ builder.Phases.Clear();
+
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+
+ features = builder.Features.ToArray();
+ phases = builder.Phases.ToArray();
+ });
+
+ // Assert
+ Assert.Collection(
+ engine.Features,
+ f => Assert.Same(features[0], f),
+ f => Assert.Same(features[1], f));
+
+ Assert.Collection(
+ engine.Phases,
+ p => Assert.Same(phases[0], p),
+ p => Assert.Same(phases[1], p));
+ }
+
+ [Fact]
+ public void CreateDesignTime_Lambda_AddsFeaturesAndPhases()
+ {
+ // Arrange
+ IRazorEngineFeature[] features = null;
+ IRazorEnginePhase[] phases = null;
+
+ // Act
+ var engine = RazorEngine.CreateDesignTime(builder =>
+ {
+ builder.Features.Clear();
+ builder.Phases.Clear();
+
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+ builder.Features.Add(Mock.Of<IRazorEngineFeature>());
+
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+ builder.Phases.Add(Mock.Of<IRazorEnginePhase>());
+
+ features = builder.Features.ToArray();
+ phases = builder.Phases.ToArray();
+ });
+
+ // Assert
+ Assert.Collection(
+ engine.Features,
+ f => Assert.Same(features[0], f),
+ f => Assert.Same(features[1], f));
+
+ Assert.Collection(
+ engine.Phases,
+ p => Assert.Same(phases[0], p),
+ p => Assert.Same(phases[1], p));
+ }
+
+ private static void AssertDefaultRuntimeTargetExtensions(RazorEngine engine)
+ {
+ var feature = engine.Features.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
+ Assert.NotNull(feature);
+
+ Assert.Collection(
+ feature.TargetExtensions,
+ extension => Assert.IsType<MetadataAttributeTargetExtension>(extension),
+ extension => Assert.IsType<DefaultTagHelperTargetExtension>(extension),
+ extension => Assert.IsType<PreallocatedAttributeTargetExtension>(extension));
+ }
+
+ private static void AssertDefaultRuntimeFeatures(IEnumerable<IRazorEngineFeature> features)
+ {
+ Assert.Collection(
+ features,
+ feature => Assert.IsType<DefaultRazorDirectiveFeature>(feature),
+ feature => Assert.IsType<DefaultRazorTargetExtensionFeature>(feature),
+ feature => Assert.IsType<DefaultMetadataIdentifierFeature>(feature),
+ feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
+ feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
+ feature => Assert.IsType<MetadataAttributePass>(feature),
+ feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
+ feature => Assert.IsType<DefaultRazorParserOptionsFeature>(feature),
+ feature => Assert.IsType<DefaultRazorCodeGenerationOptionsFeature>(feature),
+ feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
+ }
+
+ private static void AssertDefaultRuntimePhases(IReadOnlyList<IRazorEnginePhase> phases)
+ {
+ Assert.Collection(
+ phases,
+ phase => Assert.IsType<DefaultRazorParsingPhase>(phase),
+ phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
+ phase => Assert.IsType<DefaultRazorTagHelperBinderPhase>(phase),
+ phase => Assert.IsType<DefaultRazorIntermediateNodeLoweringPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDocumentClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDirectiveClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorOptimizationPhase>(phase),
+ phase => Assert.IsType<DefaultRazorCSharpLoweringPhase>(phase));
+ }
+
+ private static void AssertDefaultDesignTimeTargetExtensions(RazorEngine engine)
+ {
+ var feature = engine.Features.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
+ Assert.NotNull(feature);
+
+ Assert.Collection(
+ feature.TargetExtensions,
+ extension => Assert.IsType<MetadataAttributeTargetExtension>(extension),
+ extension => Assert.IsType<DefaultTagHelperTargetExtension>(extension),
+ extension => Assert.IsType<DesignTimeDirectiveTargetExtension>(extension));
+ }
+
+ private static void AssertDefaultDesignTimeFeatures(IEnumerable<IRazorEngineFeature> features)
+ {
+ Assert.Collection(
+ features,
+ feature => Assert.IsType<DefaultRazorDirectiveFeature>(feature),
+ feature => Assert.IsType<DefaultRazorTargetExtensionFeature>(feature),
+ feature => Assert.IsType<DefaultMetadataIdentifierFeature>(feature),
+ feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
+ feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
+ feature => Assert.IsType<MetadataAttributePass>(feature),
+ feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
+ feature => Assert.IsType<DefaultRazorParserOptionsFeature>(feature),
+ feature => Assert.IsType<DefaultRazorCodeGenerationOptionsFeature>(feature),
+ feature => Assert.IsType<SuppressChecksumOptionsFeature>(feature),
+ feature => Assert.IsType<DesignTimeDirectivePass>(feature));
+ }
+
+ private static void AssertDefaultDesignTimePhases(IReadOnlyList<IRazorEnginePhase> phases)
+ {
+ Assert.Collection(
+ phases,
+ phase => Assert.IsType<DefaultRazorParsingPhase>(phase),
+ phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
+ phase => Assert.IsType<DefaultRazorTagHelperBinderPhase>(phase),
+ phase => Assert.IsType<DefaultRazorIntermediateNodeLoweringPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDocumentClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDirectiveClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorOptimizationPhase>(phase),
+ phase => Assert.IsType<DefaultRazorCSharpLoweringPhase>(phase));
+ }
+ }
+#pragma warning restore CS0618 // Type or member is obsolete
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs
new file mode 100644
index 0000000000..cfdb9f023d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorParserFeatureFlagsTest.cs
@@ -0,0 +1,33 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorParserFeatureFlagsTest
+ {
+ [Fact]
+ public void Create_LatestVersion_AllowsMinimizedBooleanTagHelperAttributes()
+ {
+ // Arrange & Act
+ var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version_2_1);
+
+ // Assert
+ Assert.True(context.AllowMinimizedBooleanTagHelperAttributes);
+ Assert.True(context.AllowHtmlCommentsInTagHelpers);
+ }
+
+ [Fact]
+ public void Create_OlderVersion_DoesNotAllowMinimizedBooleanTagHelperAttributes()
+ {
+ // Arrange & Act
+ var context = RazorParserFeatureFlags.Create(RazorLanguageVersion.Version_1_1);
+
+ // Assert
+ Assert.False(context.AllowMinimizedBooleanTagHelperAttributes);
+ Assert.False(context.AllowHtmlCommentsInTagHelpers);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineBuilderExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineBuilderExtensionsTest.cs
new file mode 100644
index 0000000000..f0a57128c3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineBuilderExtensionsTest.cs
@@ -0,0 +1,103 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorProjectEngineBuilderExtensionsTest
+ {
+ [Fact]
+ public void SetImportFeature_SetsTheImportFeature()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ var testFeature1 = Mock.Of<IImportProjectFeature>();
+ var testFeature2 = Mock.Of<IImportProjectFeature>();
+ builder.Features.Add(testFeature1);
+ builder.Features.Add(testFeature2);
+ var newFeature = Mock.Of<IImportProjectFeature>();
+
+ // Act
+ builder.SetImportFeature(newFeature);
+
+ // Assert
+ var feature = Assert.Single(builder.Features);
+ Assert.Same(newFeature, feature);
+ }
+
+ [Fact]
+ public void AddTargetExtension_CreatesAndAddsToTargetExtensionFeatureIfItDoesNotExist()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ var expectedExtension = Mock.Of<ICodeTargetExtension>();
+
+ // Act
+ builder.AddTargetExtension(expectedExtension);
+
+ // Assert
+ var feature = Assert.Single(builder.Features);
+ var codeTargetExtensionFeature = Assert.IsAssignableFrom<IRazorTargetExtensionFeature>(feature);
+ var extensions = Assert.Single(codeTargetExtensionFeature.TargetExtensions);
+ Assert.Same(expectedExtension, extensions);
+ }
+
+ [Fact]
+ public void AddTargetExtension_UsesExistingFeatureIfExistsAndAddsTo()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ var codeTargetExtensionFeature = new DefaultRazorTargetExtensionFeature();
+ builder.Features.Add(codeTargetExtensionFeature);
+ var expectedExtension = Mock.Of<ICodeTargetExtension>();
+
+ // Act
+ builder.AddTargetExtension(expectedExtension);
+
+ // Assert
+ var feature = Assert.Single(builder.Features);
+ Assert.Same(codeTargetExtensionFeature, feature);
+ var extensions = Assert.Single(codeTargetExtensionFeature.TargetExtensions);
+ Assert.Same(expectedExtension, extensions);
+ }
+
+ [Fact]
+ public void AddDirective_CreatesAndAddsToDirectiveFeatureIfItDoesNotExist()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ var expectedDirective = Mock.Of<DirectiveDescriptor>();
+
+ // Act
+ builder.AddDirective(expectedDirective);
+
+ // Assert
+ var feature = Assert.Single(builder.Features);
+ var directiveFeature = Assert.IsAssignableFrom<IRazorDirectiveFeature>(feature);
+ var directive = Assert.Single(directiveFeature.Directives);
+ Assert.Same(expectedDirective, directive);
+ }
+
+ [Fact]
+ public void AddDirective_UsesExistingFeatureIfExistsAndAddsTo()
+ {
+ // Arrange
+ var builder = new DefaultRazorProjectEngineBuilder(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+ var directiveFeature = new DefaultRazorDirectiveFeature();
+ builder.Features.Add(directiveFeature);
+ var expecteDirective = Mock.Of<DirectiveDescriptor>();
+
+ // Act
+ builder.AddDirective(expecteDirective);
+
+ // Assert
+ var feature = Assert.Single(builder.Features);
+ Assert.Same(directiveFeature, feature);
+ var directive = Assert.Single(directiveFeature.Directives);
+ Assert.Same(expecteDirective, directive);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineFeatureBaseTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineFeatureBaseTest.cs
new file mode 100644
index 0000000000..8344e787c7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineFeatureBaseTest.cs
@@ -0,0 +1,34 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorProjectEngineFeatureBaseTest
+ {
+ [Fact]
+ public void ProjectEngineSetter_CallsOnInitialized()
+ {
+ // Arrange
+ var testFeature = new TestFeature();
+
+ // Act
+ testFeature.ProjectEngine = Mock.Of<RazorProjectEngine>();
+
+ // Assert
+ Assert.Equal(1, testFeature.InitializationCount);
+ }
+
+ private class TestFeature : RazorProjectEngineFeatureBase
+ {
+ public int InitializationCount { get; private set; }
+
+ protected override void OnInitialized()
+ {
+ InitializationCount++;
+ }
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineTest.cs
new file mode 100644
index 0000000000..d901c16199
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectEngineTest.cs
@@ -0,0 +1,85 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Razor.Language.Extensions;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test
+{
+ public class RazorProjectEngineTest
+ {
+ [Fact]
+ public void CreateDesignTime_Lambda_AddsFeaturesAndPhases()
+ {
+ // Arrange
+
+ // Act
+ var engine = RazorProjectEngine.Create(RazorConfiguration.Default, Mock.Of<RazorProjectFileSystem>());
+
+ // Assert
+ AssertDefaultPhases(engine);
+ AssertDefaultFeatures(engine);
+ AssertDefaultDirectives(engine);
+ AssertDefaultTargetExtensions(engine);
+ }
+
+ private static void AssertDefaultPhases(RazorProjectEngine engine)
+ {
+ Assert.Collection(
+ engine.Phases,
+ phase => Assert.IsType<DefaultRazorParsingPhase>(phase),
+ phase => Assert.IsType<DefaultRazorSyntaxTreePhase>(phase),
+ phase => Assert.IsType<DefaultRazorTagHelperBinderPhase>(phase),
+ phase => Assert.IsType<DefaultRazorIntermediateNodeLoweringPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDocumentClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorDirectiveClassifierPhase>(phase),
+ phase => Assert.IsType<DefaultRazorOptimizationPhase>(phase),
+ phase => Assert.IsType<DefaultRazorCSharpLoweringPhase>(phase));
+ }
+
+ private static void AssertDefaultFeatures(RazorProjectEngine engine)
+ {
+ var features = engine.EngineFeatures.OrderBy(f => f.GetType().Name).ToArray();
+ Assert.Collection(
+ features,
+ feature => Assert.IsType<DefaultDirectiveSyntaxTreePass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPass>(feature),
+ feature => Assert.IsType<DefaultDocumentClassifierPassFeature>(feature),
+ feature => Assert.IsType<DefaultMetadataIdentifierFeature>(feature),
+ feature => Assert.IsType<DefaultRazorCodeGenerationOptionsFeature>(feature),
+ feature => Assert.IsType<DefaultRazorDirectiveFeature>(feature),
+ feature => Assert.IsType<DefaultRazorParserOptionsFeature>(feature),
+ feature => Assert.IsType<DefaultRazorTargetExtensionFeature>(feature),
+ feature => Assert.IsType<DefaultTagHelperOptimizationPass>(feature),
+ feature => Assert.IsType<DesignTimeDirectivePass>(feature),
+ feature => Assert.IsType<DirectiveRemovalOptimizationPass>(feature),
+ feature => Assert.IsType<HtmlNodeOptimizationPass>(feature),
+ feature => Assert.IsType<MetadataAttributePass>(feature),
+ feature => Assert.IsType<PreallocatedTagHelperAttributeOptimizationPass>(feature));
+ }
+
+ private static void AssertDefaultDirectives(RazorProjectEngine engine)
+ {
+ var feature = engine.EngineFeatures.OfType<IRazorDirectiveFeature>().FirstOrDefault();
+ Assert.NotNull(feature);
+ Assert.Empty(feature.Directives);
+ }
+
+ private static void AssertDefaultTargetExtensions(RazorProjectEngine engine)
+ {
+ var feature = engine.EngineFeatures.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
+ Assert.NotNull(feature);
+
+ var extensions = feature.TargetExtensions.OrderBy(f => f.GetType().Name).ToArray();
+ Assert.Collection(
+ extensions,
+ extension => Assert.IsType<DefaultTagHelperTargetExtension>(extension),
+ extension => Assert.IsType<DesignTimeDirectiveTargetExtension>(extension),
+ extension => Assert.IsType<MetadataAttributeTargetExtension>(extension),
+ extension => Assert.IsType<PreallocatedAttributeTargetExtension>(extension));
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectItemTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectItemTest.cs
new file mode 100644
index 0000000000..e1e95b2cc0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectItemTest.cs
@@ -0,0 +1,104 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorProjectItemTest
+ {
+ [Fact]
+ public void CombinedPath_ReturnsPathIfBasePathIsEmpty()
+ {
+ // Arrange
+ var emptyBasePath = "/";
+ var path = "/foo/bar.cshtml";
+ var projectItem = new TestRazorProjectItem(path, basePath: emptyBasePath);
+
+ // Act
+ var combinedPath = projectItem.CombinedPath;
+
+ // Assert
+ Assert.Equal(path, combinedPath);
+ }
+
+ [Theory]
+ [InlineData("/root", "/root/foo/bar.cshtml")]
+ [InlineData("root/subdir", "root/subdir/foo/bar.cshtml")]
+ public void CombinedPath_ConcatsPaths(string basePath, string expected)
+ {
+ // Arrange
+ var path = "/foo/bar.cshtml";
+ var projectItem = new TestRazorProjectItem(path, basePath: basePath);
+
+ // Act
+ var combinedPath = projectItem.CombinedPath;
+
+ // Assert
+ Assert.Equal(expected, combinedPath);
+ }
+
+ [Theory]
+ [InlineData("/Home/Index")]
+ [InlineData("EditUser")]
+ public void Extension_ReturnsNullIfFileDoesNotHaveExtension(string path)
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem(path, basePath: "/views");
+
+ // Act
+ var extension = projectItem.Extension;
+
+ // Assert
+ Assert.Null(extension);
+ }
+
+ [Theory]
+ [InlineData("/Home/Index.cshtml", ".cshtml")]
+ [InlineData("/Home/Index.en-gb.cshtml", ".cshtml")]
+ [InlineData("EditUser.razor", ".razor")]
+ public void Extension_ReturnsFileExtension(string path, string expected)
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem(path, basePath: "/views");
+
+ // Act
+ var extension = projectItem.Extension;
+
+ // Assert
+ Assert.Equal(expected, extension);
+ }
+
+ [Theory]
+ [InlineData("Home/Index.cshtml", "Index.cshtml")]
+ [InlineData("/Accounts/Customers/Manage-en-us.razor", "Manage-en-us.razor")]
+ public void FileName_ReturnsFileNameWithExtension(string path, string expected)
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem(path, basePath: "/");
+
+ // Act
+ var fileName = projectItem.FileName;
+
+ // Assert
+ Assert.Equal(expected, fileName);
+ }
+
+ [Theory]
+ [InlineData("Home/Index", "Home/Index")]
+ [InlineData("Home/Index.cshtml", "Home/Index")]
+ [InlineData("/Accounts/Customers/Manage.en-us.razor", "/Accounts/Customers/Manage.en-us")]
+ [InlineData("/Accounts/Customers/Manage-en-us.razor", "/Accounts/Customers/Manage-en-us")]
+ public void PathWithoutExtension_ExcludesExtension(string path, string expected)
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem(path, basePath: "/");
+
+ // Act
+ var fileName = projectItem.FilePathWithoutExtension;
+
+ // Assert
+ Assert.Equal(expected, fileName);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectTest.cs
new file mode 100644
index 0000000000..7831db3521
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorProjectTest.cs
@@ -0,0 +1,333 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Testing;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorProjectTest
+ {
+ [Fact]
+ public void NormalizeAndEnsureValidPath_DoesNotModifyPath()
+ {
+ // Arrange
+ var project = new TestRazorProject();
+
+ // Act
+ var path = project.NormalizeAndEnsureValidPath("/Views/Home/Index.cshtml");
+
+ // Assert
+ Assert.Equal("/Views/Home/Index.cshtml", path);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ public void NormalizeAndEnsureValidPath_ThrowsIfPathIsNullOrEmpty(string path)
+ {
+ // Arrange
+ var project = new TestRazorProject();
+
+ // Act and Assert
+ ExceptionAssert.ThrowsArgumentNullOrEmptyString(() => project.NormalizeAndEnsureValidPath(path), "path");
+ }
+
+ [Theory]
+ [InlineData("foo")]
+ [InlineData("~/foo")]
+ [InlineData("\\foo")]
+ public void NormalizeAndEnsureValidPath_ThrowsIfPathDoesNotStartWithForwardSlash(string path)
+ {
+ // Arrange
+ var project = new TestRazorProject();
+
+ // Act and Assert
+ ExceptionAssert.ThrowsArgument(
+ () => project.NormalizeAndEnsureValidPath(path),
+ "path",
+ "Path must begin with a forward slash '/'.");
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_ReturnsEmptySequenceIfPathIsAtRoot()
+ {
+ // Arrange
+ var project = new TestRazorProject();
+
+ // Act
+ var result = project.FindHierarchicalItems("/", "File.cshtml");
+
+ // Assert
+ Assert.Empty(result);
+ }
+
+ [Theory]
+ [InlineData("_ViewStart.cshtml")]
+ [InlineData("_ViewImports.cshtml")]
+ public void FindHierarchicalItems_ReturnsItemsForPath(string fileName)
+ {
+ // Arrange
+ var path = "/Views/Home/Index.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem($"/{fileName}"),
+ CreateProjectItem($"/Views/{fileName}"),
+ CreateProjectItem($"/Views/Home/{fileName}")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(path, $"{fileName}");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item => Assert.Equal($"/Views/Home/{fileName}", item.FilePath),
+ item => Assert.Equal($"/Views/{fileName}", item.FilePath),
+ item => Assert.Equal($"/{fileName}", item.FilePath));
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_ReturnsItemsForPathAtRoot()
+ {
+ // Arrange
+ var path = "/Index.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/File.cshtml")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item => Assert.Equal("/File.cshtml", item.FilePath));
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_DoesNotIncludePassedInItem()
+ {
+ // Arrange
+ var path = "/Areas/MyArea/Views/Home/File.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/Views/Home/File.cshtml"),
+ CreateProjectItem("/Areas/MyArea/Views/File.cshtml"),
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/Areas/File.cshtml"),
+ CreateProjectItem("/File.cshtml"),
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item => Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.FilePath),
+ item => Assert.Equal("/Areas/MyArea/File.cshtml", item.FilePath),
+ item => Assert.Equal("/Areas/File.cshtml", item.FilePath),
+ item => Assert.Equal("/File.cshtml", item.FilePath));
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_ReturnsEmptySequenceIfPassedInItemWithFileNameIsAtRoot()
+ {
+ // Arrange
+ var path = "/File.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/File.cshtml")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(path, "File.cshtml");
+
+ // Assert
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_IncludesNonExistentFiles()
+ {
+ // Arrange
+ var path = "/Areas/MyArea/Views/Home/Test.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/File.cshtml")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/File.cshtml", item.FilePath);
+ Assert.True(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/File.cshtml", item.FilePath);
+ Assert.True(item.Exists);
+ });
+ }
+
+ [Theory]
+ [InlineData("/Areas")]
+ [InlineData("/Areas/")]
+ public void FindHierarchicalItems_WithBasePath(string basePath)
+ {
+ // Arrange
+ var path = "/Areas/MyArea/Views/Home/Test.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/File.cshtml")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/File.cshtml", item.FilePath);
+ Assert.True(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ });
+ }
+
+ [Theory]
+ [InlineData("/Areas/MyArea/Views")]
+ [InlineData("/Areas/MyArea/Views/")]
+ public void FindHierarchicalItems_WithNestedBasePath(string basePath)
+ {
+ // Arrange
+ var path = "/Areas/MyArea/Views/Home/Test.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/File.cshtml")
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ },
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ });
+ }
+
+ [Theory]
+ [InlineData("/Areas/MyArea/Views/Home")]
+ [InlineData("/Areas/MyArea/Views/Home/")]
+ public void FindHierarchicalItems_WithFileAtBasePath(string basePath)
+ {
+ // Arrange
+ var path = "/Areas/MyArea/Views/Home/Test.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/File.cshtml"),
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
+
+ // Assert
+ Assert.Collection(
+ result,
+ item =>
+ {
+ Assert.Equal("/Areas/MyArea/Views/Home/File.cshtml", item.FilePath);
+ Assert.False(item.Exists);
+ });
+ }
+
+ [Fact]
+ public void FindHierarchicalItems_ReturnsEmptySequenceIfPathIsNotASubPathOfBasePath()
+ {
+ // Arrange
+ var basePath = "/Pages";
+ var path = "/Areas/MyArea/Views/Home/Test.cshtml";
+ var items = new List<RazorProjectItem>
+ {
+ CreateProjectItem("/Areas/MyArea/File.cshtml"),
+ CreateProjectItem("/File.cshtml"),
+ };
+ var project = new TestRazorProject(items);
+
+ // Act
+ var result = project.FindHierarchicalItems(basePath, path, "File.cshtml");
+
+ // Assert
+ Assert.Empty(result);
+ }
+
+ private RazorProjectItem CreateProjectItem(string path)
+ {
+ var projectItem = new Mock<RazorProjectItem>();
+ projectItem.SetupGet(f => f.FilePath).Returns(path);
+ projectItem.SetupGet(f => f.Exists).Returns(true);
+ return projectItem.Object;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSourceDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSourceDocumentTest.cs
new file mode 100644
index 0000000000..9c05f2851c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSourceDocumentTest.cs
@@ -0,0 +1,219 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorSourceDocumentTest
+ {
+ [Fact]
+ public void ReadFrom()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent();
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(content, "file.cshtml");
+
+ // Assert
+ Assert.IsType<StreamSourceDocument>(document);
+ Assert.Equal("file.cshtml", document.FilePath);
+ Assert.Same(Encoding.UTF8, document.Encoding);
+ }
+
+ [Fact]
+ public void ReadFrom_WithEncoding()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(encoding: Encoding.UTF32);
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(content, "file.cshtml", Encoding.UTF32);
+
+ // Assert
+ Assert.Equal("file.cshtml", document.FilePath);
+ Assert.Same(Encoding.UTF32, Assert.IsType<StreamSourceDocument>(document).Encoding);
+ }
+
+ [Fact]
+ public void ReadFrom_WithProperties()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(encoding: Encoding.UTF32);
+ var properties = new RazorSourceDocumentProperties("c:\\myapp\\filePath.cshtml", "filePath.cshtml");
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(content, Encoding.UTF32, properties);
+
+ // Assert
+ Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Same(Encoding.UTF32, Assert.IsType<StreamSourceDocument>(document).Encoding);
+ }
+
+ [Fact]
+ public void ReadFrom_EmptyStream_WithEncoding()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(content: string.Empty, encoding: Encoding.UTF32);
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(content, "file.cshtml", Encoding.UTF32);
+
+ // Assert
+ Assert.Equal("file.cshtml", document.FilePath);
+ Assert.Same(Encoding.UTF32, Assert.IsType<StreamSourceDocument>(document).Encoding);
+ }
+
+ [Fact]
+ public void ReadFrom_ProjectItem()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("filePath.cshtml", "c:\\myapp\\filePath.cshtml", "filePath.cshtml", "c:\\myapp\\");
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Equal(projectItem.Content, ReadContent(document));
+ }
+
+ [Fact]
+ public void ReadFrom_ProjectItem_NoRelativePath()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("filePath.cshtml", "c:\\myapp\\filePath.cshtml", basePath: "c:\\myapp\\");
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Equal(projectItem.Content, ReadContent(document));
+ }
+
+ [Fact]
+ public void ReadFrom_ProjectItem_FallbackToRelativePath()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("filePath.cshtml", relativePhysicalPath: "filePath.cshtml", basePath: "c:\\myapp\\");
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal("filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Equal(projectItem.Content, ReadContent(document));
+ }
+
+ [Fact]
+ public void ReadFrom_ProjectItem_FallbackToFileName()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("filePath.cshtml", basePath: "c:\\myapp\\");
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal("filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Equal(projectItem.Content, ReadContent(document));
+ }
+
+ [Fact]
+ public void Create_WithoutEncoding()
+ {
+ // Arrange
+ var content = "Hello world";
+ var fileName = "some-file-name";
+
+ // Act
+ var document = RazorSourceDocument.Create(content, fileName);
+
+ // Assert
+ Assert.Equal(fileName, document.FilePath);
+ Assert.Equal(content, ReadContent(document));
+ Assert.Same(Encoding.UTF8, document.Encoding);
+ }
+
+ [Fact]
+ public void Create_WithEncoding()
+ {
+ // Arrange
+ var content = "Hello world";
+ var fileName = "some-file-name";
+ var encoding = Encoding.UTF32;
+
+ // Act
+ var document = RazorSourceDocument.Create(content, fileName, encoding);
+
+ // Assert
+ Assert.Equal(fileName, document.FilePath);
+ Assert.Equal(content, ReadContent(document));
+ Assert.Same(encoding, document.Encoding);
+ }
+
+ [Fact]
+ public void Create_WithProperties()
+ {
+ // Arrange
+ var content = "Hello world";
+ var properties = new RazorSourceDocumentProperties("c:\\myapp\\filePath.cshtml", "filePath.cshtml");
+
+ // Act
+ var document = RazorSourceDocument.Create(content, Encoding.UTF32, properties);
+
+ // Assert
+ Assert.Equal("c:\\myapp\\filePath.cshtml", document.FilePath);
+ Assert.Equal("filePath.cshtml", document.RelativePath);
+ Assert.Equal(content, ReadContent(document));
+ Assert.Same(Encoding.UTF32, Assert.IsType<StringSourceDocument>(document).Encoding);
+ }
+
+ [Fact]
+ public void ReadFrom_WithProjectItem_FallbackToFilePath_WhenRelativePhysicalPathIsNull()
+ {
+ // Arrange
+ var filePath = "filePath.cshtml";
+ var projectItem = new TestRazorProjectItem(filePath, relativePhysicalPath: null);
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal(filePath, document.FilePath);
+ Assert.Equal(filePath, document.RelativePath);
+ }
+
+ [Fact]
+ public void ReadFrom_WithProjectItem_UsesRelativePhysicalPath()
+ {
+ // Arrange
+ var filePath = "filePath.cshtml";
+ var relativePhysicalPath = "relative-path.cshtml";
+ var projectItem = new TestRazorProjectItem(filePath, relativePhysicalPath: relativePhysicalPath);
+
+ // Act
+ var document = RazorSourceDocument.ReadFrom(projectItem);
+
+ // Assert
+ Assert.Equal(relativePhysicalPath, document.FilePath);
+ Assert.Equal(relativePhysicalPath, document.RelativePath);
+ }
+
+ private static string ReadContent(RazorSourceDocument razorSourceDocument)
+ {
+ var buffer = new char[razorSourceDocument.Length];
+ razorSourceDocument.CopyTo(0, buffer, 0, buffer.Length);
+
+ return new string(buffer);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSyntaxTreeTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSyntaxTreeTest.cs
new file mode 100644
index 0000000000..09b36651ce
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorSyntaxTreeTest.cs
@@ -0,0 +1,79 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test
+{
+ public class RazorSyntaxTreeTest
+ {
+ [Fact]
+ public void Parse_CanParseEmptyDocument()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create(string.Empty);
+
+ // Act
+ var syntaxTree = RazorSyntaxTree.Parse(source);
+
+ // Assert
+ Assert.NotNull(syntaxTree);
+ Assert.Empty(syntaxTree.Diagnostics);
+ }
+
+ [Fact]
+ public void Parse_Persists_FilePath()
+ {
+ // Arrange
+ var filePath = "test.cshtml";
+ var source = TestRazorSourceDocument.Create("@if (true) { @if(false) { <div>@something.</div> } }", filePath: filePath);
+
+ // Act
+ var syntaxTree = RazorSyntaxTree.Parse(source);
+
+ // Assert
+ Assert.Empty(syntaxTree.Diagnostics);
+ Assert.NotNull(syntaxTree);
+
+ var spans = new List<SyntaxTreeNode>();
+ GetChildren(syntaxTree.Root);
+ Assert.All(spans, node => Assert.Equal(filePath, node.Start.FilePath));
+
+ void GetChildren(SyntaxTreeNode node)
+ {
+ if (node is Block block)
+ {
+ foreach (var child in block.Children)
+ {
+ GetChildren(child);
+ }
+ }
+ else
+ {
+ spans.Add(node);
+ }
+ }
+ }
+
+ [Fact]
+ public void Parse_UseDirectiveTokenizer_ParsesUntilFirstDirective()
+ {
+ // Arrange
+ var source = TestRazorSourceDocument.Create("\r\n \r\n @*SomeComment*@ \r\n @tagHelperPrefix \"SomePrefix\"\r\n<html>\r\n@if (true) {\r\n @if(false) { <div>@something.</div> } \r\n}");
+ var options = RazorParserOptions.Create(builder => builder.ParseLeadingDirectives = true);
+
+ // Act
+ var syntaxTree = RazorSyntaxTree.Parse(source, options);
+
+ // Assert
+ Assert.NotNull(syntaxTree);
+ Assert.Equal(6, syntaxTree.Root.Children.Count);
+ var block = Assert.IsType<Block>(syntaxTree.Root.Children[4]);
+ Assert.Equal(BlockKindInternal.Directive, block.Type);
+ Assert.Empty(syntaxTree.Diagnostics);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorTemplateEngineTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorTemplateEngineTest.cs
new file mode 100644
index 0000000000..07a777570f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/RazorTemplateEngineTest.cs
@@ -0,0 +1,359 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Linq;
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class RazorTemplateEngineTest
+ {
+ [Fact]
+ public void GetImports_CanQueryInformationOnNonExistentFileWithoutImports()
+ {
+ // Arrange
+ var fileSystem = new TestRazorProjectFileSystem();
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml"
+ }
+ };
+ var projectItemToQuery = fileSystem.GetItem("/Views/Home/Index.cshtml");
+
+ // Act
+ var imports = templateEngine.GetImports(projectItemToQuery);
+
+ // Assert
+ Assert.Empty(imports);
+ }
+
+ [Fact]
+ public void GetImports_CanQueryInformationOnNonExistentFileWithImports()
+ {
+ // Arrange
+ var path = "/Views/Home/MyImport.cshtml";
+ var projectItem = new TestRazorProjectItem(path);
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml"
+ }
+ };
+ var projectItemToQuery = project.GetItem("/Views/Home/Index.cshtml");
+
+ // Act
+ var imports = templateEngine.GetImports(projectItemToQuery);
+
+ // Assert
+ var import = Assert.Single(imports);
+ Assert.Equal(projectItem.FilePath, import.FilePath);
+ }
+
+ [Fact]
+ public void GenerateCode_ThrowsIfItemCannotBeFound()
+ {
+ // Arrange
+ var project = new TestRazorProjectFileSystem(new RazorProjectItem[] { });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act & Assert
+ var ex = Assert.Throws<InvalidOperationException>(
+ () => templateEngine.GenerateCode("/does-not-exist.cstml"));
+ Assert.Equal("The item '/does-not-exist.cstml' could not be found.", ex.Message);
+ }
+
+ [Fact]
+ public void SettingOptions_ThrowsIfValueIsNull()
+ {
+ // Arrange
+ var project = new TestRazorProjectFileSystem(new RazorProjectItem[] { });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgumentNull(
+ () => templateEngine.Options = null,
+ "value");
+ }
+
+ [Fact]
+ public void GenerateCode_WithPath()
+ {
+ // Arrange
+ var path = "/Views/Home/Index.cshtml";
+ var projectItem = new TestRazorProjectItem(path);
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode(path);
+
+ // Assert
+ Assert.NotNull(cSharpDocument);
+ Assert.NotEmpty(cSharpDocument.GeneratedCode);
+ Assert.Empty(cSharpDocument.Diagnostics);
+ }
+
+ [Fact]
+ public void GenerateCode_ThrowsIfProjectItemCannotBeFound()
+ {
+ // Arrange
+ var path = "/Views/Home/Index.cshtml";
+ var project = new TestRazorProjectFileSystem(new RazorProjectItem[] { });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act & Assert
+ var ex = Assert.Throws<InvalidOperationException>(() => templateEngine.GenerateCode(path));
+ Assert.Equal($"The item '{path}' could not be found.", ex.Message);
+ }
+
+ [Fact]
+ public void GenerateCode_WithProjectItem()
+ {
+ // Arrange
+ var path = "/Views/Home/Index.cshtml";
+ var projectItem = new TestRazorProjectItem(path);
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act
+ var cSharpDocument = templateEngine.GenerateCode(projectItem);
+
+ // Assert
+ Assert.NotNull(cSharpDocument);
+ Assert.NotEmpty(cSharpDocument.GeneratedCode);
+ Assert.Empty(cSharpDocument.Diagnostics);
+ }
+
+ [Fact]
+ public void GenerateCode_WithCodeDocument()
+ {
+ // Arrange
+ var path = "/Views/Home/Index.cshtml";
+ var projectItem = new TestRazorProjectItem(path);
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project);
+
+ // Act - 1
+ var codeDocument = templateEngine.CreateCodeDocument(path);
+
+ // Assert - 1
+ Assert.NotNull(codeDocument);
+
+ // Act - 2
+ var cSharpDocument = templateEngine.GenerateCode(codeDocument);
+
+ // Assert
+ Assert.NotNull(cSharpDocument);
+ Assert.NotEmpty(cSharpDocument.GeneratedCode);
+ Assert.Empty(cSharpDocument.Diagnostics);
+ }
+
+ [Fact]
+ public void CreateCodeDocument_ThrowsIfPathCannotBeFound()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml");
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml",
+ }
+ };
+
+ // Act & Assert
+ var ex = Assert.Throws<InvalidOperationException>(() => templateEngine.CreateCodeDocument("/DoesNotExist.cshtml"));
+
+ // Assert
+ Assert.Equal("The item '/DoesNotExist.cshtml' could not be found.", ex.Message);
+ }
+
+ [Fact]
+ public void CreateCodeDocument_IncludesImportsIfFileIsPresent()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml");
+ var import1 = new TestRazorProjectItem("/MyImport.cshtml");
+ var import2 = new TestRazorProjectItem("/Views/Home/MyImport.cshtml");
+ var project = new TestRazorProjectFileSystem(new[] { import1, import2, projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml",
+ }
+ };
+
+ // Act
+ var codeDocument = templateEngine.CreateCodeDocument("/Views/Home/Index.cshtml");
+
+ // Assert
+ Assert.Collection(codeDocument.Imports,
+ import => Assert.Equal("/MyImport.cshtml", import.FilePath),
+ import => Assert.Equal("/Views/Home/MyImport.cshtml", import.FilePath));
+ }
+
+ [Fact]
+ public void CreateCodeDocument_IncludesDefaultImportIfNotNull()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml");
+ var import1 = new TestRazorProjectItem("/MyImport.cshtml");
+ var import2 = new TestRazorProjectItem("/Views/Home/MyImport.cshtml");
+ var project = new TestRazorProjectFileSystem(new[] { import1, import2, projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var defaultImport = RazorSourceDocument.ReadFrom(new MemoryStream(), "Default.cshtml");
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml",
+ DefaultImports = defaultImport,
+ }
+ };
+
+ // Act
+ var codeDocument = templateEngine.CreateCodeDocument(projectItem);
+
+ // Assert
+ Assert.Collection(codeDocument.Imports,
+ import => Assert.Same(defaultImport, import),
+ import => Assert.Equal("/MyImport.cshtml", import.FilePath),
+ import => Assert.Equal("/Views/Home/MyImport.cshtml", import.FilePath));
+ }
+
+ [Fact]
+ public void CreateCodeDocument_NullImportFileName_IncludesDefaultImportIfNotNull()
+ {
+ // Arrange
+ var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml");
+ var project = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var defaultImport = RazorSourceDocument.ReadFrom(new MemoryStream(), "Default.cshtml");
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ DefaultImports = defaultImport,
+ }
+ };
+
+ // Act
+ var codeDocument = templateEngine.CreateCodeDocument(projectItem);
+
+ // Assert
+ Assert.Collection(codeDocument.Imports,
+ import => Assert.Same(defaultImport, import));
+ }
+
+ [Fact]
+ public void GetImportItems_WithPath_ReturnsAllImportsForFile()
+ {
+ // Arrange
+ var expected = new[] { "/Views/Home/MyImport.cshtml", "/Views/MyImport.cshtml", "/MyImport.cshtml" };
+ var project = new TestRazorProjectFileSystem();
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml"
+ }
+ };
+
+ // Act
+ var imports = templateEngine.GetImportItems("/Views/Home/Index.cshtml");
+
+ // Assert
+ var paths = imports.Select(i => i.FilePath);
+ Assert.Equal(expected, paths);
+ }
+
+ [Fact]
+ public void GetImportItems_WithItem_ReturnsAllImportsForFile()
+ {
+ // Arrange
+ var expected = new[] { "/Views/Home/MyImport.cshtml", "/Views/MyImport.cshtml", "/MyImport.cshtml" };
+ var projectItem = new TestRazorProjectItem("/Views/Home/Index.cshtml");
+ var fileSystem = new TestRazorProjectFileSystem(new[] { projectItem });
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, fileSystem)
+ {
+ Options =
+ {
+ ImportsFileName = "MyImport.cshtml"
+ }
+ };
+
+ // Act
+ var imports = templateEngine.GetImportItems(projectItem);
+
+ // Assert
+ var paths = imports.Select(i => i.FilePath);
+ Assert.Equal(expected, paths);
+ }
+
+ [Fact]
+ public void CreateCodeDocument_WithFileSystemProject_ReturnsCorrectItems()
+ {
+ // Arrange
+ var testFolder = Path.Combine(
+ TestProject.GetProjectDirectory(typeof(DefaultRazorProjectFileSystemTest)),
+ "TestFiles",
+ "DefaultRazorProjectFileSystem");
+
+ var project = new DefaultRazorProjectFileSystem(testFolder);
+ var razorEngine = RazorProjectEngine.Create().Engine;
+ var templateEngine = new RazorTemplateEngine(razorEngine, project)
+ {
+ Options =
+ {
+ ImportsFileName = "_ViewImports.cshtml"
+ }
+ };
+
+ // Act
+ var codeDocument = templateEngine.CreateCodeDocument("/Views/Home/Index.cshtml");
+
+ // Assert
+ Assert.Collection(
+ codeDocument.Imports,
+ item =>
+ {
+ Assert.Equal(Path.Combine(testFolder, "_ViewImports.cshtml"), item.FilePath);
+ Assert.Equal("_ViewImports.cshtml", item.RelativePath);
+
+ },
+ item =>
+ {
+ Assert.Equal(Path.Combine(testFolder, "Views", "_ViewImports.cshtml"), item.FilePath);
+ Assert.Equal(Path.Combine("Views", "_ViewImports.cshtml"), item.RelativePath);
+
+ },
+ item =>
+ {
+ Assert.Equal(Path.Combine(testFolder, "Views", "Home", "_ViewImports.cshtml"), item.FilePath);
+ Assert.Equal(Path.Combine("Views", "Home", "_ViewImports.cshtml"), item.RelativePath);
+
+ });
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceChangeTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceChangeTest.cs
new file mode 100644
index 0000000000..f3f1b9320e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceChangeTest.cs
@@ -0,0 +1,197 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class SourceChangeTest
+ {
+ [Fact]
+ public void SourceChange_ConstructorSetsDefaults_WhenNotProvided()
+ {
+ // Arrange & Act
+ var change = new SourceChange(15, 7, "Hello");
+
+ // Assert
+ Assert.Equal(15, change.Span.AbsoluteIndex);
+ Assert.Equal(-1, change.Span.CharacterIndex);
+ Assert.Null(change.Span.FilePath);
+ Assert.Equal(7, change.Span.Length);
+ Assert.Equal(-1, change.Span.LineIndex);
+ Assert.Equal("Hello", change.NewText);
+ }
+
+ [Fact]
+ public void IsDelete_IsTrue_WhenOldLengthIsPositive_AndNewLengthIsZero()
+ {
+ // Arrange & Act
+ var change = new SourceChange(3, 5, string.Empty);
+
+ // Assert
+ Assert.True(change.IsDelete);
+ }
+
+ [Fact]
+ public void IsInsert_IsTrue_WhenOldLengthIsZero_AndNewLengthIsPositive()
+ {
+ // Arrange & Act
+ var change = new SourceChange(3, 0, "Hello");
+
+ // Assert
+ Assert.True(change.IsInsert);
+ }
+
+ [Fact]
+ public void IsReplace_IsTrue_WhenOldLengthIsPositive_AndNewLengthIsPositive()
+ {
+ // Arrange & Act
+ var change = new SourceChange(3, 5, "Hello");
+
+ // Assert
+ Assert.True(change.IsReplace);
+ }
+
+ [Fact]
+ public void GetEditedContent_ForDelete_ReturnsNewContent()
+ {
+ // Arrange
+ var text = "Hello, World";
+
+ var change = new SourceChange(2, 2, string.Empty);
+
+ // Act
+ var result = change.GetEditedContent(text, 1);
+
+ // Act
+ Assert.Equal("Hlo, World", result);
+ }
+
+ [Fact]
+ public void GetEditedContent_ForInsert_ReturnsNewContent()
+ {
+ // Arrange
+ var text = "Hello, World";
+
+ var change = new SourceChange(2, 0, "heyo");
+
+ // Act
+ var result = change.GetEditedContent(text, 1);
+
+ // Act
+ Assert.Equal("Hheyoello, World", result);
+ }
+
+ [Fact]
+ public void GetEditedContent_ForReplace_ReturnsNewContent()
+ {
+ // Arrange
+ var text = "Hello, World";
+
+ var change = new SourceChange(2, 2, "heyo");
+
+ // Act
+ var result = change.GetEditedContent(text, 1);
+
+ // Act
+ Assert.Equal("Hheyolo, World", result);
+ }
+
+ [Fact]
+ public void GetEditedContent_Span_ReturnsNewContent()
+ {
+ // Arrange
+ var builder = new SpanBuilder(new SourceLocation(0, 0, 0));
+ builder.Accept(new RawTextSymbol(new SourceLocation(0, 0, 0), "Hello, "));
+ builder.Accept(new RawTextSymbol(new SourceLocation(7, 0, 7), "World"));
+
+ var span = new Span(builder);
+
+ var change = new SourceChange(2, 2, "heyo");
+
+ // Act
+ var result = change.GetEditedContent(span);
+
+ // Act
+ Assert.Equal("Heheyoo, World", result);
+ }
+
+ [Fact]
+ public void GetOffSet_SpanIsOwner_ReturnsOffset()
+ {
+ // Arrange
+ var builder = new SpanBuilder(new SourceLocation(13, 0, 0));
+ builder.Accept(new RawTextSymbol(new SourceLocation(13, 0, 13), "Hello, "));
+ builder.Accept(new RawTextSymbol(new SourceLocation(20, 0, 20), "World"));
+
+ var span = new Span(builder);
+
+ var change = new SourceChange(15, 2, "heyo");
+
+ // Act
+ var result = change.GetOffset(span);
+
+ // Act
+ Assert.Equal(2, result);
+ }
+
+ [Fact]
+ public void GetOffSet_SpanIsNotOwnerOfChange_ThrowsException()
+ {
+ // Arrange
+ var builder = new SpanBuilder(new SourceLocation(13, 0, 0));
+ builder.Accept(new RawTextSymbol(new SourceLocation(13, 0, 13), "Hello, "));
+ builder.Accept(new RawTextSymbol(new SourceLocation(20, 0, 20), "World"));
+
+ var span = new Span(builder);
+
+ var change = new SourceChange(12, 2, "heyo");
+
+ var expected = $"The node '{span}' is not the owner of change '{change}'.";
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(() => { change.GetOffset(span); });
+ Assert.Equal(expected, exception.Message);
+ }
+
+ [Fact]
+ public void GetOrigninalText_SpanIsOwner_ReturnsContent()
+ {
+ // Arrange
+ var builder = new SpanBuilder(new SourceLocation(13, 0, 0));
+ builder.Accept(new RawTextSymbol(new SourceLocation(13, 0, 13), "Hello, "));
+ builder.Accept(new RawTextSymbol(new SourceLocation(20, 0, 20), "World"));
+
+ var span = new Span(builder);
+
+ var change = new SourceChange(15, 2, "heyo");
+
+ // Act
+ var result = change.GetOriginalText(span);
+
+ // Act
+ Assert.Equal("ll", result);
+ }
+
+ [Fact]
+ public void GetOrigninalText_SpanIsOwner_ReturnsContent_ZeroLengthSpan()
+ {
+ // Arrange
+ var builder = new SpanBuilder(new SourceLocation(13, 0, 0));
+ builder.Accept(new RawTextSymbol(new SourceLocation(13, 0, 13), "Hello, "));
+ builder.Accept(new RawTextSymbol(new SourceLocation(20, 0, 20), "World"));
+
+ var span = new Span(builder);
+
+ var change = new SourceChange(15, 0, "heyo");
+
+ // Act
+ var result = change.GetOriginalText(span);
+
+ // Act
+ Assert.Equal(string.Empty, result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceLocationTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceLocationTest.cs
new file mode 100644
index 0000000000..c2401c56b7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceLocationTest.cs
@@ -0,0 +1,110 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Testing;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class SourceLocationTest
+ {
+ [Fact]
+ public void ConstructorWithLineAndCharacterIndexSetsAssociatedProperties()
+ {
+ // Act
+ var loc = new SourceLocation(0, 42, 24);
+
+ // Assert
+ Assert.Null(loc.FilePath);
+ Assert.Equal(0, loc.AbsoluteIndex);
+ Assert.Equal(42, loc.LineIndex);
+ Assert.Equal(24, loc.CharacterIndex);
+ }
+
+ [Fact]
+ public void Constructor_SetsFilePathAndIndexes()
+ {
+ // Arrange
+ var filePath = "some-file-path";
+ var absoluteIndex = 133;
+ var lineIndex = 23;
+ var characterIndex = 12;
+
+ // Act
+ var sourceLocation = new SourceLocation(filePath, absoluteIndex, lineIndex, characterIndex);
+
+ // Assert
+ Assert.Equal(filePath, sourceLocation.FilePath);
+ Assert.Equal(absoluteIndex, sourceLocation.AbsoluteIndex);
+ Assert.Equal(lineIndex, sourceLocation.LineIndex);
+ Assert.Equal(characterIndex, sourceLocation.CharacterIndex);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("some-file")]
+ public void GetHashCode_ReturnsSameValue_WhenEqual(string path)
+ {
+ // Arrange
+ var sourceLocationA = new SourceLocation(path, 10, 3, 4);
+ var sourceLocationB = new SourceLocation(path, 10, 3, 4);
+ var sourceLocationC = new SourceLocation(path, 10, 45, 8754);
+
+ // Act
+ var hashCodeA = sourceLocationA.GetHashCode();
+ var hashCodeB = sourceLocationB.GetHashCode();
+ var hashCodeC = sourceLocationC.GetHashCode();
+
+ // Assert
+ Assert.Equal(hashCodeA, hashCodeB);
+ Assert.Equal(hashCodeA, hashCodeC);
+ }
+
+ [Fact]
+ public void Equals_ReturnsFalse_FilePathsNullAndAbsoluteIndicesMatch()
+ {
+ // Arrange
+ var sourceLocationA = new SourceLocation(10, 3, 4);
+ var sourceLocationB = new SourceLocation(10, 45, 8754);
+
+ // Act
+ var result = sourceLocationA.Equals(sourceLocationB);
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Fact]
+ public void Equals_ReturnsFalse_IfFilePathIsDifferent()
+ {
+ // Arrange
+ var sourceLocationA = new SourceLocation(10, 3, 4);
+ var sourceLocationB = new SourceLocation("different-file", 10, 3, 4);
+
+ // Act
+ var result = sourceLocationA.Equals(sourceLocationB);
+
+ // Assert
+ Assert.False(result);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("some-file")]
+ public void Equals_ReturnsTrue_IfFilePathAndIndexesAreSame(string path)
+ {
+ // Arrange
+ var sourceLocationA = new SourceLocation(path, 10, 3, 4);
+ var sourceLocationB = new SourceLocation(path, 10, 3, 4);
+ var sourceLocationC = new SourceLocation("different-path", 10, 3, 4);
+
+ // Act
+ var result1 = sourceLocationA.Equals(sourceLocationB);
+ var result2 = sourceLocationA.Equals(sourceLocationC);
+
+ // Assert
+ Assert.True(result1);
+ Assert.False(result2);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceSpanTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceSpanTest.cs
new file mode 100644
index 0000000000..d59253c08a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/SourceSpanTest.cs
@@ -0,0 +1,117 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class SourceSpanTest
+ {
+ [Fact]
+ public void GeneratedCodeMappingsAreEqualIfDataIsEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ // Assert
+ Assert.True(left.Equals(right));
+ Assert.True(right.Equals(left));
+ Assert.True(Equals(left, right));
+ }
+
+ [Fact]
+ public void GeneratedCodeMappingsAreNotEqualIfCodeLengthIsNotEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 5),
+ new SourceSpan(new SourceLocation(5, 6, 7), 9));
+
+ // Assert
+ AssertNotEqual(left, right);
+ }
+
+ [Fact]
+ public void GeneratedCodeMappingsAreNotEqualIfStartGeneratedColumnIsNotEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 8), 8));
+
+ // Assert
+ AssertNotEqual(left, right);
+ }
+
+ [Fact]
+ public void GeneratedCodeMappingsAreNotEqualIfStartColumnIsNotEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 8), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ // Assert
+ AssertNotEqual(left, right);
+ }
+
+ [Fact]
+ public void GeneratedCodeMappingsAreNotEqualIfStartLineIsNotEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 5, 7), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 1, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 8));
+
+ // Assert
+ AssertNotEqual(left, right);
+ }
+
+ [Fact]
+ public void GeneratedCodeMappingsAreNotEqualIfAbsoluteIndexIsNotEqual()
+ {
+ // Arrange
+ var left = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(4, 6, 7), 8));
+
+ var right = new SourceMapping(
+ new SourceSpan(new SourceLocation(1, 2, 3), 4),
+ new SourceSpan(new SourceLocation(5, 6, 7), 9));
+
+ // Assert
+ AssertNotEqual(left, right);
+ }
+
+ private void AssertNotEqual(SourceMapping left, SourceMapping right)
+ {
+ Assert.False(left == right);
+ Assert.False(left.Equals(right));
+ Assert.False(right.Equals(left));
+ Assert.False(Equals(left, right));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StreamSourceDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StreamSourceDocumentTest.cs
new file mode 100644
index 0000000000..f377450320
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StreamSourceDocumentTest.cs
@@ -0,0 +1,200 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class StreamSourceDocumentTest
+ {
+ [Fact]
+ public void FilePath()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+
+ // Act
+ var document = new StreamSourceDocument(stream, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: "file.cshtml", relativePath: null));
+
+ // Assert
+ Assert.Equal("file.cshtml", document.FilePath);
+ }
+
+ [Fact]
+ public void FilePath_Null()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+
+ // Act
+ var document = new StreamSourceDocument(stream, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: null));
+
+ // Assert
+ Assert.Null(document.FilePath);
+ }
+
+ [Fact]
+ public void RelativePath()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+
+ // Act
+ var document = new StreamSourceDocument(stream, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: "file.cshtml"));
+
+ // Assert
+ Assert.Equal("file.cshtml", document.RelativePath);
+ }
+
+ [Fact]
+ public void RelativePath_Null()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+
+ // Act
+ var document = new StreamSourceDocument(stream, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: null));
+
+ // Assert
+ Assert.Null(document.RelativePath);
+ }
+
+ [Fact]
+ public void GetChecksum_ReturnsCopiedChecksum()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+ var document = new StreamSourceDocument(stream, null, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var firstChecksum = document.GetChecksum();
+ var secondChecksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(firstChecksum, secondChecksum);
+ Assert.NotSame(firstChecksum, secondChecksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF8()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF8);
+ var document = new StreamSourceDocument(stream, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 70, 180, 84, 105, 70, 79, 152, 31, 71, 157, 46, 159, 50, 83, 1, 243, 222, 48, 90, 18 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF32AutoDetect()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var stream = CreateBOMStream(content, Encoding.UTF32);
+ var document = new StreamSourceDocument(stream, null, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 159, 154, 109, 89, 250, 163, 165, 108, 2, 112, 34, 4, 247, 161, 82, 168, 77, 213, 107, 71 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Fact]
+ public void ConstructedWithoutEncoding_DetectsEncoding()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(encoding: Encoding.UTF32);
+
+ // Act
+ var document = new StreamSourceDocument(content, null, RazorSourceDocumentProperties.Default);
+
+ // Assert
+ Assert.IsType<StreamSourceDocument>(document);
+ Assert.Equal(Encoding.UTF32, document.Encoding);
+ }
+
+ [Fact]
+ public void ConstructedWithoutEncoding_EmptyStream_DetectsEncoding()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(content: string.Empty, encoding: Encoding.UTF32);
+
+ // Act
+ var document = new StreamSourceDocument(content, null, RazorSourceDocumentProperties.Default);
+
+ // Assert
+ Assert.IsType<StreamSourceDocument>(document);
+ Assert.Equal(Encoding.UTF32, document.Encoding);
+ }
+
+ [Fact]
+ public void FailsOnMismatchedEncoding()
+ {
+ // Arrange
+ var content = TestRazorSourceDocument.CreateStreamContent(encoding: Encoding.UTF32);
+ var expectedMessage = Resources.FormatMismatchedContentEncoding(Encoding.UTF8.EncodingName, Encoding.UTF32.EncodingName);
+
+ // Act & Assert
+ var exception = Assert.Throws<InvalidOperationException>(
+ () => new StreamSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default));
+ Assert.Equal(expectedMessage, exception.Message);
+ }
+
+ [Theory]
+ [InlineData(100000)]
+ [InlineData(RazorSourceDocument.LargeObjectHeapLimitInChars)]
+ [InlineData(RazorSourceDocument.LargeObjectHeapLimitInChars + 2)]
+ [InlineData(RazorSourceDocument.LargeObjectHeapLimitInChars * 2 - 1)]
+ [InlineData(RazorSourceDocument.LargeObjectHeapLimitInChars * 2)]
+ public void DetectsSizeOfStreamForLargeContent(int contentLength)
+ {
+ // Arrange
+ var content = new string('a', contentLength);
+ var stream = TestRazorSourceDocument.CreateStreamContent(content);
+
+ // Act
+ var document = new StreamSourceDocument(stream, null, RazorSourceDocumentProperties.Default);
+
+ // Assert
+ var streamDocument = Assert.IsType<StreamSourceDocument>(document);
+ Assert.IsType<LargeTextSourceDocument>(streamDocument._innerSourceDocument);
+ Assert.Same(Encoding.UTF8, document.Encoding);
+ Assert.Equal(content, ReadContent(document));
+ }
+
+ private static MemoryStream CreateBOMStream(string content, Encoding encoding)
+ {
+ var preamble = encoding.GetPreamble();
+ var contentBytes = encoding.GetBytes(content);
+ var buffer = new byte[preamble.Length + contentBytes.Length];
+ preamble.CopyTo(buffer, 0);
+ contentBytes.CopyTo(buffer, preamble.Length);
+ var stream = new MemoryStream(buffer);
+ return stream;
+ }
+
+ private static string ReadContent(RazorSourceDocument razorSourceDocument)
+ {
+ var buffer = new char[razorSourceDocument.Length];
+ razorSourceDocument.CopyTo(0, buffer, 0, buffer.Length);
+
+ return new string(buffer);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StringSourceDocumentTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StringSourceDocumentTest.cs
new file mode 100644
index 0000000000..8306d2bf80
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/StringSourceDocumentTest.cs
@@ -0,0 +1,516 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Text;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class StringSourceDocumentTest
+ {
+ [Fact]
+ public void GetChecksum_ReturnsCopiedChecksum()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var firstChecksum = document.GetChecksum();
+ var secondChecksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(firstChecksum, secondChecksum);
+ Assert.NotSame(firstChecksum, secondChecksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF8()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 46, 247, 189, 230, 8, 206, 84, 4, 233, 125, 95, 4, 47, 149, 248, 159, 28, 35, 40, 113 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Fact]
+ public void GetChecksum_ComputesCorrectChecksum_UTF32()
+ {
+ // Arrange
+ var content = "Hello World!";
+ var document = new StringSourceDocument(content, Encoding.UTF32, RazorSourceDocumentProperties.Default);
+ var expectedChecksum = new byte[] { 8, 149, 159, 15, 242, 255, 115, 227, 219, 78, 61, 53, 127, 239, 77, 239, 215, 140, 248, 44 };
+
+ // Act
+ var checksum = document.GetChecksum();
+
+ // Assert
+ Assert.Equal(expectedChecksum, checksum);
+ }
+
+ [Fact]
+ public void Indexer_ProvidesCharacterAccessToContent()
+ {
+ // Arrange
+ var expectedContent = "Hello, World!";
+ var indexerBuffer = new char[expectedContent.Length];
+ var document = new StringSourceDocument(expectedContent, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ for (var i = 0; i < document.Length; i++)
+ {
+ indexerBuffer[i] = document[i];
+ }
+
+ // Assert
+ var output = new string(indexerBuffer);
+ Assert.Equal(expectedContent, output);
+ }
+
+ [Fact]
+ public void Length()
+ {
+ // Arrange
+ var expectedContent = "Hello, World!";
+ var document = new StringSourceDocument(expectedContent, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act & Assert
+ Assert.Equal(expectedContent.Length, document.Length);
+ }
+
+ [Fact]
+ public void FilePath()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ // Act
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: "file.cshtml", relativePath: null));
+
+ // Assert
+ Assert.Equal("file.cshtml", document.FilePath);
+ }
+
+ [Fact]
+ public void FilePath_Null()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ // Act
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: null));
+
+ // Assert
+ Assert.Null(document.FilePath);
+ }
+
+ [Fact]
+ public void RelativePath()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ // Act
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: "file.cshtml"));
+
+ // Assert
+ Assert.Equal("file.cshtml", document.RelativePath);
+ }
+
+ [Fact]
+ public void RelativePath_Null()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ // Act
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: null, relativePath: null));
+
+ // Assert
+ Assert.Null(document.RelativePath);
+ }
+
+ [Fact]
+ public void CopyTo_PartialCopyFromStart()
+ {
+ // Arrange
+ var content = "Hello, World!";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedContent = "Hello";
+ var charBuffer = new char[expectedContent.Length];
+
+ // Act
+ document.CopyTo(0, charBuffer, 0, expectedContent.Length);
+
+ // Assert
+ var copiedContent = new string(charBuffer);
+ Assert.Equal(expectedContent, copiedContent);
+ }
+
+ [Fact]
+ public void CopyTo_PartialCopyDestinationOffset()
+ {
+ // Arrange
+ var content = "Hello, World!";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedContent = "$Hello";
+ var charBuffer = new char[expectedContent.Length];
+ charBuffer[0] = '$';
+
+ // Act
+ document.CopyTo(0, charBuffer, 1, "Hello".Length);
+
+ // Assert
+ var copiedContent = new string(charBuffer);
+ Assert.Equal(expectedContent, copiedContent);
+ }
+
+ [Fact]
+ public void CopyTo_PartialCopySourceOffset()
+ {
+ // Arrange
+ var content = "Hello, World!";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+ var expectedContent = "World";
+ var charBuffer = new char[expectedContent.Length];
+
+ // Act
+ document.CopyTo(7, charBuffer, 0, expectedContent.Length);
+
+ // Assert
+ var copiedContent = new string(charBuffer);
+ Assert.Equal(expectedContent, copiedContent);
+ }
+
+ [Fact]
+ public void CopyTo_CanCopyMultipleTimes()
+ {
+ // Arrange
+ var content = "Hi";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act & Assert
+ //
+ // (we should be able to do this twice to prove that the underlying data isn't disposed)
+ for (var i = 0; i < 2; i++)
+ {
+ var charBuffer = new char[2];
+ document.CopyTo(0, charBuffer, 0, 2);
+ var copiedContent = new string(charBuffer);
+ Assert.Equal("Hi", copiedContent);
+ }
+ }
+
+ [Fact]
+ public void Lines_Count_EmptyDocument()
+ {
+ // Arrange
+ var content = string.Empty;
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.Count;
+
+ // Assert
+ Assert.Equal(1, actual);
+ }
+
+ [Fact]
+ public void Lines_GetLineLength_EmptyDocument()
+ {
+ // Arrange
+ var content = string.Empty;
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLineLength(0);
+
+ // Assert
+ Assert.Equal(0, actual);
+ }
+
+ [Fact]
+ public void Lines_GetLineLength_TrailingNewlineDoesNotStartNewLine()
+ {
+ // Arrange
+ var content = "hello\n";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLineLength(0);
+
+ // Assert
+ Assert.Equal(6, actual);
+ }
+
+ [Fact]
+ public void Lines_GetLineLength_TrailingNewlineDoesNotStartNewLine_CRLF()
+ {
+ // Arrange
+ var content = "hello\r\n";
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLineLength(0);
+
+ // Assert
+ Assert.Equal(7, actual);
+ }
+
+ [Fact]
+ public void Lines_Simple_Document()
+ {
+ // Arrange
+ var content = new StringBuilder()
+ .Append("The quick brown").Append('\n')
+ .Append("fox").Append("\r\n")
+ .Append("jumps over the lazy dog.")
+ .ToString();
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 16, 5, 24 }, actual);
+ }
+
+ [Fact]
+ public void Lines_CRLF_OnlyCountsAsASingleNewLine()
+ {
+ // Arrange
+ var content = "Hello\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 7, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_CR_IsNewLine()
+ {
+ // Arrange
+ var content = "Hello\rWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 6 }, actual);
+ }
+
+ // CR handling is stateful in the parser, making sure we properly reset the state.
+ [Fact]
+ public void Lines_CR_IsNewLine_MultipleCRs()
+ {
+ // Arrange
+ var content = "Hello\rBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 5, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_LF_IsNewLine()
+ {
+ // Arrange
+ var content = "Hello\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_Unicode0085_IsNewLine()
+ {
+ // Arrange
+ var content = "Hello\u0085World!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_Unicode2028_IsNewLine()
+ {
+ // Arrange
+ var content = "Hello\u2028World!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_Unicode2029_IsNewLine()
+ {
+ // Arrange
+ var content = "Hello\u2029World!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = GetAllSourceMappings(document);
+
+ // Assert
+ Assert.Equal(new int[] { 6, 6 }, actual);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_IncludesAbsoluteIndexAndDocument()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: "Hi.cshtml", relativePath: null));
+
+ // Act
+ var actual = document.Lines.GetLocation(1);
+
+ // Assert
+ Assert.Equal("Hi.cshtml", actual.FilePath);
+ Assert.Equal(1, actual.AbsoluteIndex);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_PrefersRelativePath()
+ {
+ // Arrange
+ var content = "Hello, World!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, new RazorSourceDocumentProperties(filePath: "Hi.cshtml", relativePath: "Bye.cshtml"));
+
+ // Act
+ var actual = document.Lines.GetLocation(1);
+
+ // Assert
+ Assert.Equal("Bye.cshtml", actual.FilePath);
+ Assert.Equal(1, actual.AbsoluteIndex);
+ }
+
+ // Beginnings of lines are special because the BinarySearch in the implementation
+ // will succeed. It's a different code path.
+ [Fact]
+ public void Lines_GetLocation_FirstCharacter()
+ {
+ // Arrange
+ var content = "Hello\nBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLocation(0);
+
+ // Assert
+ Assert.Equal(0, actual.LineIndex);
+ Assert.Equal(0, actual.CharacterIndex);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_EndOfFirstLine()
+ {
+ // Arrange
+ var content = "Hello\nBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLocation(5);
+
+ // Assert
+ Assert.Equal(0, actual.LineIndex);
+ Assert.Equal(5, actual.CharacterIndex);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_InteriorLine()
+ {
+ // Arrange
+ var content = "Hello\nBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLocation(7);
+
+ // Assert
+ Assert.Equal(1, actual.LineIndex);
+ Assert.Equal(1, actual.CharacterIndex);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_StartOfLastLine()
+ {
+ // Arrange
+ var content = "Hello\nBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLocation(11);
+
+ // Assert
+ Assert.Equal(2, actual.LineIndex);
+ Assert.Equal(0, actual.CharacterIndex);
+ }
+
+ [Fact]
+ public void Lines_GetLocation_EndOfLastLine()
+ {
+ // Arrange
+ var content = "Hello\nBig\r\nWorld!";
+
+ var document = new StringSourceDocument(content, Encoding.UTF8, RazorSourceDocumentProperties.Default);
+
+ // Act
+ var actual = document.Lines.GetLocation(16);
+
+ // Assert
+ Assert.Equal(2, actual.LineIndex);
+ Assert.Equal(5, actual.CharacterIndex);
+ }
+
+ private static int[] GetAllSourceMappings(RazorSourceDocument source)
+ {
+ var lines = new int[source.Lines.Count];
+ for (var i = 0; i < lines.Length; i++)
+ {
+ lines[i] = source.Lines.GetLineLength(i);
+ }
+
+ return lines;
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperBinderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperBinderTest.cs
new file mode 100644
index 0000000000..8530e7ebf9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperBinderTest.cs
@@ -0,0 +1,524 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TagHelperBinderTest
+ {
+ [Fact]
+ public void GetBinding_ReturnsBindingWithInformation()
+ {
+ // Arrange
+ var divTagHelper = TagHelperDescriptorBuilder.Create("DivTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build();
+ var expectedDescriptors = new[] { divTagHelper };
+ var expectedAttributes = new[]
+ {
+ new KeyValuePair<string, string>("class", "something")
+ };
+ var tagHelperBinder = new TagHelperBinder("th:", expectedDescriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "th:div",
+ attributes: expectedAttributes,
+ parentTagName: "body",
+ parentIsTagHelper: false);
+
+ // Assert
+ Assert.Equal(expectedDescriptors, bindingResult.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
+ Assert.Equal("th:div", bindingResult.TagName);
+ Assert.Equal("body", bindingResult.ParentTagName);
+ Assert.Equal(expectedAttributes, bindingResult.Attributes);
+ Assert.Equal("th:", bindingResult.TagHelperPrefix);
+ Assert.Equal(divTagHelper.TagMatchingRules, bindingResult.GetBoundRules(divTagHelper), TagMatchingRuleDescriptorComparer.CaseSensitive);
+ }
+
+ public static TheoryData RequiredParentData
+ {
+ get
+ {
+ var strongPDivParent = TagHelperDescriptorBuilder.Create("StrongTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("p"))
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("strong")
+ .RequireParentTag("div"))
+ .Build();
+ var catchAllPParent = TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("*")
+ .RequireParentTag("p"))
+ .Build();
+
+ return new TheoryData<
+ string, // tagName
+ string, // parentTagName
+ IEnumerable<TagHelperDescriptor>, // availableDescriptors
+ IEnumerable<TagHelperDescriptor>> // expectedDescriptors
+ {
+ {
+ "strong",
+ "p",
+ new[] { strongPDivParent },
+ new[] { strongPDivParent }
+ },
+ {
+ "strong",
+ "div",
+ new[] { strongPDivParent, catchAllPParent },
+ new[] { strongPDivParent }
+ },
+ {
+ "strong",
+ "p",
+ new[] { strongPDivParent, catchAllPParent },
+ new[] { strongPDivParent, catchAllPParent }
+ },
+ {
+ "custom",
+ "p",
+ new[] { strongPDivParent, catchAllPParent },
+ new[] { catchAllPParent }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(RequiredParentData))]
+ public void GetBinding_ReturnsBindingResultWithDescriptorsParentTags(
+ string tagName,
+ string parentTagName,
+ object availableDescriptors,
+ object expectedDescriptors)
+ {
+ // Arrange
+ var tagHelperBinder = new TagHelperBinder(null, (IEnumerable<TagHelperDescriptor>)availableDescriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName,
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: parentTagName,
+ parentIsTagHelper: false);
+
+ // Assert
+ Assert.Equal((IEnumerable<TagHelperDescriptor>)expectedDescriptors, bindingResult.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
+ }
+
+ public static TheoryData RequiredAttributeData
+ {
+ get
+ {
+ var divDescriptor = TagHelperDescriptorBuilder.Create("DivTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("div")
+ .RequireAttributeDescriptor(attribute => attribute.Name("style")))
+ .Build();
+ var inputDescriptor = TagHelperDescriptorBuilder.Create("InputTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireAttributeDescriptor(attribute => attribute.Name("class"))
+ .RequireAttributeDescriptor(attribute => attribute.Name("style")))
+ .Build();
+ var inputWildcardPrefixDescriptor = TagHelperDescriptorBuilder.Create("InputWildCardAttribute", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName("input")
+ .RequireAttributeDescriptor(attribute =>
+ attribute
+ .Name("nodashprefix")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch)))
+ .Build();
+ var catchAllDescriptor = TagHelperDescriptorBuilder.Create("CatchAllTagHelper", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName(TagHelperMatchingConventions.ElementCatchAllName)
+ .RequireAttributeDescriptor(attribute => attribute.Name("class")))
+ .Build();
+ var catchAllDescriptor2 = TagHelperDescriptorBuilder.Create("CatchAllTagHelper2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName(TagHelperMatchingConventions.ElementCatchAllName)
+ .RequireAttributeDescriptor(attribute => attribute.Name("custom"))
+ .RequireAttributeDescriptor(attribute => attribute.Name("class")))
+ .Build();
+ var catchAllWildcardPrefixDescriptor = TagHelperDescriptorBuilder.Create("CatchAllWildCardAttribute", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule =>
+ rule
+ .RequireTagName(TagHelperMatchingConventions.ElementCatchAllName)
+ .RequireAttributeDescriptor(attribute =>
+ attribute
+ .Name("prefix-")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch)))
+ .Build();
+ var defaultAvailableDescriptors =
+ new[] { divDescriptor, inputDescriptor, catchAllDescriptor, catchAllDescriptor2 };
+ var defaultWildcardDescriptors =
+ new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor };
+ Func<string, KeyValuePair<string, string>> kvp =
+ (name) => new KeyValuePair<string, string>(name, "test value");
+
+ return new TheoryData<
+ string, // tagName
+ IReadOnlyList<KeyValuePair<string, string>>, // providedAttributes
+ IEnumerable<TagHelperDescriptor>, // availableDescriptors
+ IEnumerable<TagHelperDescriptor>> // expectedDescriptors
+ {
+ {
+ "div",
+ new[] { kvp("custom") },
+ defaultAvailableDescriptors,
+ null
+ },
+ { "div", new[] { kvp("style") }, defaultAvailableDescriptors, new[] { divDescriptor } },
+ { "div", new[] { kvp("class") }, defaultAvailableDescriptors, new[] { catchAllDescriptor } },
+ {
+ "div",
+ new[] { kvp("class"), kvp("style") },
+ defaultAvailableDescriptors,
+ new[] { divDescriptor, catchAllDescriptor }
+ },
+ {
+ "div",
+ new[] { kvp("class"), kvp("style"), kvp("custom") },
+ defaultAvailableDescriptors,
+ new[] { divDescriptor, catchAllDescriptor, catchAllDescriptor2 }
+ },
+ {
+ "input",
+ new[] { kvp("class"), kvp("style") },
+ defaultAvailableDescriptors,
+ new[] { inputDescriptor, catchAllDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("nodashprefixA") },
+ defaultWildcardDescriptors,
+ new[] { inputWildcardPrefixDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("nodashprefix-ABC-DEF"), kvp("random") },
+ defaultWildcardDescriptors,
+ new[] { inputWildcardPrefixDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("prefixABCnodashprefix") },
+ defaultWildcardDescriptors,
+ null
+ },
+ {
+ "input",
+ new[] { kvp("prefix-") },
+ defaultWildcardDescriptors,
+ null
+ },
+ {
+ "input",
+ new[] { kvp("nodashprefix") },
+ defaultWildcardDescriptors,
+ null
+ },
+ {
+ "input",
+ new[] { kvp("prefix-A") },
+ defaultWildcardDescriptors,
+ new[] { catchAllWildcardPrefixDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("prefix-ABC-DEF"), kvp("random") },
+ defaultWildcardDescriptors,
+ new[] { catchAllWildcardPrefixDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("prefix-abc"), kvp("nodashprefix-def") },
+ defaultWildcardDescriptors,
+ new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor }
+ },
+ {
+ "input",
+ new[] { kvp("class"), kvp("prefix-abc"), kvp("onclick"), kvp("nodashprefix-def"), kvp("style") },
+ defaultWildcardDescriptors,
+ new[] { inputWildcardPrefixDescriptor, catchAllWildcardPrefixDescriptor }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(RequiredAttributeData))]
+ public void GetBinding_ReturnsBindingResultDescriptorsWithRequiredAttributes(
+ string tagName,
+ IReadOnlyList<KeyValuePair<string, string>> providedAttributes,
+ object availableDescriptors,
+ object expectedDescriptors)
+ {
+ // Arrange
+ var tagHelperBinder = new TagHelperBinder(null, (IReadOnlyList<TagHelperDescriptor>)availableDescriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(tagName, providedAttributes, parentTagName: "p", parentIsTagHelper: false);
+
+ // Assert
+ Assert.Equal((IEnumerable<TagHelperDescriptor>)expectedDescriptors, bindingResult?.Descriptors, TagHelperDescriptorComparer.CaseSensitive);
+ }
+
+ [Fact]
+ public void GetBinding_ReturnsNullBindingResultPrefixAsTagName()
+ {
+ // Arrange
+ var catchAllDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName(TagHelperMatchingConventions.ElementCatchAllName))
+ .Build();
+ var descriptors = new[] { catchAllDescriptor };
+ var tagHelperBinder = new TagHelperBinder("th", descriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "th",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ Assert.Null(bindingResult);
+ }
+
+ [Fact]
+ public void GetBinding_ReturnsBindingResultCatchAllDescriptorsForPrefixedTags()
+ {
+ // Arrange
+ var catchAllDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName(TagHelperMatchingConventions.ElementCatchAllName))
+ .Build();
+ var descriptors = new[] { catchAllDescriptor };
+ var tagHelperBinder = new TagHelperBinder("th:", descriptors);
+
+ // Act
+ var bindingResultDiv = tagHelperBinder.GetBinding(
+ tagName: "th:div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+ var bindingResultSpan = tagHelperBinder.GetBinding(
+ tagName: "th:span",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ var descriptor = Assert.Single(bindingResultDiv.Descriptors);
+ Assert.Same(catchAllDescriptor, descriptor);
+ descriptor = Assert.Single(bindingResultSpan.Descriptors);
+ Assert.Same(catchAllDescriptor, descriptor);
+ }
+
+ [Fact]
+ public void GetBinding_ReturnsBindingResultDescriptorsForPrefixedTags()
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build();
+ var descriptors = new[] { divDescriptor };
+ var tagHelperBinder = new TagHelperBinder("th:", descriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "th:div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ var descriptor = Assert.Single(bindingResult.Descriptors);
+ Assert.Same(divDescriptor, descriptor);
+ }
+
+ [Theory]
+ [InlineData("*")]
+ [InlineData("div")]
+ public void GetBinding_ReturnsNullForUnprefixedTags(string tagName)
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName(tagName))
+ .Build();
+ var descriptors = new[] { divDescriptor };
+ var tagHelperBinder = new TagHelperBinder("th:", descriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ Assert.Null(bindingResult);
+ }
+
+ [Fact]
+ public void GetDescriptors_ReturnsNothingForUnregisteredTags()
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build();
+ var spanDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("span"))
+ .Build();
+ var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor };
+ var tagHelperBinder = new TagHelperBinder(null, descriptors);
+
+ // Act
+ var tagHelperBinding = tagHelperBinder.GetBinding(
+ tagName: "foo",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ Assert.Null(tagHelperBinding);
+ }
+
+ [Fact]
+ public void GetDescriptors_ReturnsCatchAllsWithEveryTagName()
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build();
+ var spanDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("span"))
+ .Build();
+ var catchAllDescriptor = TagHelperDescriptorBuilder.Create("foo3", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName(TagHelperMatchingConventions.ElementCatchAllName))
+ .Build();
+ var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };
+ var tagHelperBinder = new TagHelperBinder(null, descriptors);
+
+ // Act
+ var divBinding = tagHelperBinder.GetBinding(
+ tagName: "div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+ var spanBinding = tagHelperBinder.GetBinding(
+ tagName: "span",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ // For divs
+ Assert.Equal(2, divBinding.Descriptors.Count());
+ Assert.Contains(divDescriptor, divBinding.Descriptors);
+ Assert.Contains(catchAllDescriptor, divBinding.Descriptors);
+
+ // For spans
+ Assert.Equal(2, spanBinding.Descriptors.Count());
+ Assert.Contains(spanDescriptor, spanBinding.Descriptors);
+ Assert.Contains(catchAllDescriptor, spanBinding.Descriptors);
+ }
+
+ [Fact]
+ public void GetDescriptors_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool()
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div"))
+ .Build();
+ var descriptors = new TagHelperDescriptor[] { divDescriptor, divDescriptor };
+ var tagHelperBinder = new TagHelperBinder(null, descriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ var descriptor = Assert.Single(bindingResult.Descriptors);
+ Assert.Same(divDescriptor, descriptor);
+ }
+
+ [Fact]
+ public void GetBinding_DescriptorWithMultipleRules_CorrectlySelectsMatchingRules()
+ {
+ // Arrange
+ var multiRuleDescriptor = TagHelperDescriptorBuilder.Create("foo", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule
+ .RequireTagName(TagHelperMatchingConventions.ElementCatchAllName)
+ .RequireParentTag("body"))
+ .TagMatchingRuleDescriptor(rule => rule
+ .RequireTagName("div"))
+ .TagMatchingRuleDescriptor(rule => rule
+ .RequireTagName("span"))
+ .Build();
+ var descriptors = new TagHelperDescriptor[] { multiRuleDescriptor };
+ var tagHelperBinder = new TagHelperBinder(null, descriptors);
+
+ // Act
+ var binding = tagHelperBinder.GetBinding(
+ tagName: "div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "p",
+ parentIsTagHelper: false);
+
+ // Assert
+ var boundDescriptor = Assert.Single(binding.Descriptors);
+ Assert.Same(multiRuleDescriptor, boundDescriptor);
+ var boundRules = binding.GetBoundRules(boundDescriptor);
+ var boundRule = Assert.Single(boundRules);
+ Assert.Equal("div", boundRule.TagName);
+ }
+
+ [Fact]
+ public void GetBinding_PrefixedParent_ReturnsBinding()
+ {
+ // Arrange
+ var divDescriptor = TagHelperDescriptorBuilder.Create("foo1", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("div").RequireParentTag("p"))
+ .Build();
+ var pDescriptor = TagHelperDescriptorBuilder.Create("foo2", "SomeAssembly")
+ .TagMatchingRuleDescriptor(rule => rule.RequireTagName("p"))
+ .Build();
+ var descriptors = new[] { divDescriptor, pDescriptor };
+ var tagHelperBinder = new TagHelperBinder("th:", descriptors);
+
+ // Act
+ var bindingResult = tagHelperBinder.GetBinding(
+ tagName: "th:div",
+ attributes: Array.Empty<KeyValuePair<string, string>>(),
+ parentTagName: "th:p",
+ parentIsTagHelper: true);
+
+ // Assert
+ var boundDescriptor = Assert.Single(bindingResult.Descriptors);
+ Assert.Same(divDescriptor, boundDescriptor);
+ var boundRules = bindingResult.GetBoundRules(boundDescriptor);
+ var boundRule = Assert.Single(boundRules);
+ Assert.Equal("div", boundRule.TagName);
+ Assert.Equal("p", boundRule.ParentTag);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorBuilderTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorBuilderTest.cs
new file mode 100644
index 0000000000..37eef5fbfa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorBuilderTest.cs
@@ -0,0 +1,38 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TagHelperDescriptorBuilderTest
+ {
+ [Fact]
+ public void DisplayName_SetsDescriptorsDisplayName()
+ {
+ // Arrange
+ var expectedDisplayName = "ExpectedDisplayName";
+ var builder = TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly");
+
+ // Act
+ var descriptor = builder.DisplayName(expectedDisplayName).Build();
+
+ // Assert
+ Assert.Equal(expectedDisplayName, descriptor.DisplayName);
+ }
+
+ [Fact]
+ public void DisplayName_DefaultsToTypeName()
+ {
+ // Arrange
+ var expectedDisplayName = "TestTagHelper";
+ var builder = TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly");
+
+ // Act
+ var descriptor = builder.Build();
+
+ // Assert
+ Assert.Equal(expectedDisplayName, descriptor.DisplayName);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorExtensionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorExtensionsTest.cs
new file mode 100644
index 0000000000..0940661058
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperDescriptorExtensionsTest.cs
@@ -0,0 +1,64 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TagHelperDescriptorExtensionsTest
+ {
+ [Fact]
+ public void GetTypeName_ReturnsTypeName()
+ {
+ // Arrange
+ var expectedTypeName = "TestTagHelper";
+ var descriptor = TagHelperDescriptorBuilder.Create(expectedTypeName, "TestAssembly").TypeName(expectedTypeName).Build();
+
+ // Act
+ var typeName = descriptor.GetTypeName();
+
+ // Assert
+ Assert.Equal(expectedTypeName, typeName);
+ }
+
+ [Fact]
+ public void GetTypeName_ReturnsNullIfNoTypeName()
+ {
+ // Arrange
+ var descriptor = TagHelperDescriptorBuilder.Create("Test", "TestAssembly").Build();
+
+ // Act
+ var typeName = descriptor.GetTypeName();
+
+ // Assert
+ Assert.Null(typeName);
+ }
+
+ [Fact]
+ public void IsDefaultKind_ReturnsTrue_IfKindIsDefault()
+ {
+ // Arrange
+ var descriptor = TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly").Build();
+
+ // Act
+ var isDefault = descriptor.IsDefaultKind();
+
+ // Assert
+ Assert.True(isDefault);
+ }
+
+ [Fact]
+ public void IsDefaultKind_ReturnsFalse_IfKindIsNotDefault()
+ {
+ // Arrange
+ var descriptor = TagHelperDescriptorBuilder.Create("other-kind", "TestTagHelper", "TestAssembly").Build();
+
+ // Act
+ var isDefault = descriptor.IsDefaultKind();
+
+ // Assert
+ Assert.False(isDefault);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperMatchingConventionsTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperMatchingConventionsTest.cs
new file mode 100644
index 0000000000..7a1fc6c1e3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperMatchingConventionsTest.cs
@@ -0,0 +1,156 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TagHelperMatchingConventionsTest
+ {
+ public static TheoryData RequiredAttributeDescriptorData
+ {
+ get
+ {
+ // requiredAttributeDescriptor, attributeName, attributeValue, expectedResult
+ return new TheoryData<Action<RequiredAttributeDescriptorBuilder>, string, string, bool>
+ {
+ {
+ builder => builder.Name("key"),
+ "KeY",
+ "value",
+ true
+ },
+ {
+ builder => builder.Name("key"),
+ "keys",
+ "value",
+ false
+ },
+ {
+ builder => builder
+ .Name("route-")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch),
+ "ROUTE-area",
+ "manage",
+ true
+ },
+ {
+ builder => builder
+ .Name("route-")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch),
+ "routearea",
+ "manage",
+ false
+ },
+ {
+ builder => builder
+ .Name("route-")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch),
+ "route-",
+ "manage",
+ false
+ },
+ {
+ builder => builder
+ .Name("key")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch),
+ "KeY",
+ "value",
+ true
+ },
+ {
+ builder => builder
+ .Name("key")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch),
+ "keys",
+ "value",
+ false
+ },
+ {
+ builder => builder
+ .Name("key")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("value")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.FullMatch),
+ "key",
+ "value",
+ true
+ },
+ {
+ builder => builder
+ .Name("key")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("value")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.FullMatch),
+ "key",
+ "Value",
+ false
+ },
+ {
+ builder => builder
+ .Name("class")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("btn")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.PrefixMatch),
+ "class",
+ "btn btn-success",
+ true
+ },
+ {
+ builder => builder
+ .Name("class")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("btn")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.PrefixMatch),
+ "class",
+ "BTN btn-success",
+ false
+ },
+ {
+ builder => builder
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("#navigate")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.SuffixMatch),
+ "href",
+ "/home/index#navigate",
+ true
+ },
+ {
+ builder => builder
+ .Name("href")
+ .NameComparisonMode(RequiredAttributeDescriptor.NameComparisonMode.FullMatch)
+ .Value("#navigate")
+ .ValueComparisonMode(RequiredAttributeDescriptor.ValueComparisonMode.SuffixMatch),
+ "href",
+ "/home/index#NAVigate",
+ false
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(RequiredAttributeDescriptorData))]
+ public void Matches_ReturnsExpectedResult(
+ Action<RequiredAttributeDescriptorBuilder> configure,
+ string attributeName,
+ string attributeValue,
+ bool expectedResult)
+ {
+ // Arrange
+
+ var builder = new DefaultRequiredAttributeDescriptorBuilder();
+ configure(builder);
+
+ var requiredAttibute = builder.Build();
+
+ // Act
+ var result = TagHelperMatchingConventions.SatisfiesRequiredAttribute(attributeName, attributeValue, requiredAttibute);
+
+ // Assert
+ Assert.Equal(expectedResult, result);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs
new file mode 100644
index 0000000000..a24a9c8d4f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TagHelperParseTreeRewriterTests.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.AspNetCore.Razor.Language.Legacy;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Razor.Language.Test
+{
+ public class TagHelperParseTreeRewriterTests
+ {
+ public void IsComment_ReturnsTrueForSpanInHtmlCommentBlock()
+ {
+ // Arrange
+ SpanFactory spanFactory = new SpanFactory();
+
+ Span content = spanFactory.Markup("<!-- comment -->");
+ Block commentBlock = new HtmlCommentBlock(content);
+
+ // Act
+ bool actualResult = TagHelperParseTreeRewriter.IsComment(content);
+
+ // Assert
+ Assert.True(actualResult);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Home.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Home.cshtml
new file mode 100644
index 0000000000..7c5b3ca2e3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Home.cshtml
@@ -0,0 +1 @@
+home-content \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/About/About.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/About/About.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/About/About.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.txt
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/Index.txt
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/_ViewImports.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/_ViewImports.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/Home/_ViewImports.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/_ViewImports.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/_ViewImports.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/Views/_ViewImports.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/_ViewImports.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/_ViewImports.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/DefaultRazorProjectFileSystem/_ViewImports.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.cshtml
new file mode 100644
index 0000000000..f347706f3d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.cshtml
@@ -0,0 +1 @@
+@test \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt
new file mode 100644
index 0000000000..6142bc2eb1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/CustomDirective.ir.txt
@@ -0,0 +1,6 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.cshtml
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.cshtml
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt
new file mode 100644
index 0000000000..6142bc2eb1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/Empty.ir.txt
@@ -0,0 +1,6 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.cshtml
new file mode 100644
index 0000000000..46953c4542
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.cshtml
@@ -0,0 +1 @@
+Hello, World! \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt
new file mode 100644
index 0000000000..83409ed68c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/BasicIntegrationTest/HelloWorld.ir.txt
@@ -0,0 +1,8 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [13] HelloWorld.cshtml)
+ IntermediateToken - (0:0,0 [13] HelloWorld.cshtml) - Html - Hello, World!
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective.cshtml
new file mode 100644
index 0000000000..10b53aaeaf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective.cshtml
@@ -0,0 +1 @@
+@addTagHelper "*, TestAssembly"
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.codegen.cs
new file mode 100644
index 0000000000..9d90489dea
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.codegen.cs
@@ -0,0 +1,26 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AddTagHelperDirective_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.ir.txt
new file mode 100644
index 0000000000..a3c0f0d9e5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.ir.txt
@@ -0,0 +1,14 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AddTagHelperDirective_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] AddTagHelperDirective.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [2] AddTagHelperDirective.cshtml)
+ IntermediateToken - (31:0,31 [2] AddTagHelperDirective.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.mappings.txt
new file mode 100644
index 0000000000..bff77ec3f5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AddTagHelperDirective.cshtml)
+|"*, TestAssembly"|
+Generated Location: (427:10,37 [17] )
+|"*, TestAssembly"|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml
new file mode 100644
index 0000000000..8610fe90aa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml
@@ -0,0 +1,8 @@
+@addTagHelper *, TestAssembly
+
+<p class="btn">
+ <p><strong catchAll="hi">Hello</strong><strong>World</strong></p>
+ <input checked="true" />
+ <input type="checkbox" checked="true" />
+ <input type="checkbox" checked="true" catchAll="hi" />
+</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ae87635f43
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,51 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "checkbox";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper.Type = "checkbox";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..240c399ef1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,82 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] AttributeTargetingTagHelpers.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [4] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (29:0,29 [4] AttributeTargetingTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (33:2,0 [228] AttributeTargetingTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (48:2,15 [9] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (48:2,15 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (54:3,4 [3] AttributeTargetingTagHelpers.cshtml) - Html - <p>
+ TagHelper - (57:3,7 [36] AttributeTargetingTagHelpers.cshtml) - strong - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml) - Html - Hello
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - catchAll - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (75:3,25 [2] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (75:3,25 [2] AttributeTargetingTagHelpers.cshtml) - Html - hi
+ DefaultTagHelperExecute -
+ HtmlContent - (93:3,43 [62] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (93:3,43 [8] AttributeTargetingTagHelpers.cshtml) - Html - <strong>
+ IntermediateToken - (101:3,51 [5] AttributeTargetingTagHelpers.cshtml) - Html - World
+ IntermediateToken - (106:3,56 [9] AttributeTargetingTagHelpers.cshtml) - Html - </strong>
+ IntermediateToken - (115:3,65 [4] AttributeTargetingTagHelpers.cshtml) - Html - </p>
+ IntermediateToken - (119:3,69 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (125:4,4 [6] AttributeTargetingTagHelpers.cshtml) - Html - <input
+ IntermediateToken - (131:4,10 [15] AttributeTargetingTagHelpers.cshtml) - Html - checked="true"
+ IntermediateToken - (146:4,25 [3] AttributeTargetingTagHelpers.cshtml) - Html - />
+ IntermediateToken - (149:4,28 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ TagHelper - (155:5,4 [40] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ TagHelper - (201:6,4 [54] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperHtmlAttribute - - catchAll - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (249:6,52 [2] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (249:6,52 [2] AttributeTargetingTagHelpers.cshtml) - Html - hi
+ DefaultTagHelperExecute -
+ HtmlContent - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (43:2,10 [3] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (43:2,10 [3] AttributeTargetingTagHelpers.cshtml) - Html - btn
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..46733338f6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
+|*, TestAssembly|
+Generated Location: (779:14,38 [15] )
+|*, TestAssembly|
+
+Source Location: (187:5,36 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
+|true|
+Generated Location: (1727:31,42 [4] )
+|true|
+
+Source Location: (233:6,36 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml)
+|true|
+Generated Location: (2380:41,42 [4] )
+|true|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..9969972501
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,126 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2ceb35a784a30ab44eb8b621c9e61d2361841c63"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2ceb35a784a30ab44eb8b621c9e61d2361841c63", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("catchAll", new global::Microsoft.AspNetCore.Html.HtmlString("hi"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("btn"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n <p>");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("strong", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Hello");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("<strong>World</strong></p>\r\n <input checked=\"true\" />\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..1fbf6fd6c7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/AttributeTargetingTagHelpers_Runtime.ir.txt
@@ -0,0 +1,65 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_AttributeTargetingTagHelpers_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - catchAll - hi - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - btn - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [2] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (31:1,0 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ TagHelper - (33:2,0 [228] AttributeTargetingTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (48:2,15 [9] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (48:2,15 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (54:3,4 [3] AttributeTargetingTagHelpers.cshtml) - Html - <p>
+ TagHelper - (57:3,7 [36] AttributeTargetingTagHelpers.cshtml) - strong - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (79:3,29 [5] AttributeTargetingTagHelpers.cshtml) - Html - Hello
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (93:3,43 [62] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (93:3,43 [8] AttributeTargetingTagHelpers.cshtml) - Html - <strong>
+ IntermediateToken - (101:3,51 [5] AttributeTargetingTagHelpers.cshtml) - Html - World
+ IntermediateToken - (106:3,56 [9] AttributeTargetingTagHelpers.cshtml) - Html - </strong>
+ IntermediateToken - (115:3,65 [4] AttributeTargetingTagHelpers.cshtml) - Html - </p>
+ IntermediateToken - (119:3,69 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (125:4,4 [6] AttributeTargetingTagHelpers.cshtml) - Html - <input
+ IntermediateToken - (131:4,10 [15] AttributeTargetingTagHelpers.cshtml) - Html - checked="true"
+ IntermediateToken - (146:4,25 [3] AttributeTargetingTagHelpers.cshtml) - Html - />
+ IntermediateToken - (149:4,28 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ TagHelper - (155:5,4 [40] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperProperty - (168:5,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ DefaultTagHelperProperty - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (187:5,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (195:5,44 [6] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ TagHelper - (201:6,4 [54] AttributeTargetingTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperProperty - (214:6,17 [8] AttributeTargetingTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ DefaultTagHelperProperty - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (233:6,36 [4] AttributeTargetingTagHelpers.cshtml) - CSharp - true
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml)
+ IntermediateToken - (255:6,58 [2] AttributeTargetingTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml
new file mode 100644
index 0000000000..69b68e07c5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml
@@ -0,0 +1,26 @@
+@functions {
+ public async Task<string> Foo()
+ {
+ return "Bar";
+ }
+}
+
+<section>
+ <h1>Basic Asynchronous Expression Test</h1>
+ <p>Basic Asynchronous Expression: @await Foo()</p>
+ <p>Basic Asynchronous Template: @(await Foo())</p>
+ <p>Basic Asynchronous Statement: @{ await Foo(); }</p>
+ <p>Basic Asynchronous Statement Nested: @{ <b>@await Foo()</b> }</p>
+ <p>Basic Incomplete Asynchronous Statement: @await</p>
+</section>
+
+<section>
+ <h1>Advanced Asynchronous Expression Test</h1>
+ <p>Advanced Asynchronous Expression: @await Foo(1, 2)</p>
+ <p>Advanced Asynchronous Expression Extended: @await Foo.Bar(1, 2)</p>
+ <p>Advanced Asynchronous Template: @(await Foo("bob", true))</p>
+ <p>Advanced Asynchronous Statement: @{ await Foo(something, hello: "world"); }</p>
+ <p>Advanced Asynchronous Statement Extended: @{ await Foo.Bar(1, 2) }</p>
+ <p>Advanced Asynchronous Statement Nested: @{ <b>@await Foo(boolValue: false)</b> }</p>
+ <p>Advanced Incomplete Asynchronous Statement: @await ("wrrronggg")</p>
+</section> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.codegen.cs
new file mode 100644
index 0000000000..6baa07bacf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.codegen.cs
@@ -0,0 +1,95 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo();
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo();
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo();
+
+#line default
+#line hidden
+
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo();
+
+#line default
+#line hidden
+
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await;
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo(1, 2);
+
+#line default
+#line hidden
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo.Bar(1, 2);
+
+#line default
+#line hidden
+#line 21 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo("bob", true);
+
+#line default
+#line hidden
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo(something, hello: "world");
+
+#line default
+#line hidden
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo.Bar(1, 2)
+
+#line default
+#line hidden
+
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await Foo(boolValue: false);
+
+#line default
+#line hidden
+
+#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ __o = await ("wrrronggg");
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+
+ public async Task<string> Foo()
+ {
+ return "Bar";
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.ir.txt
new file mode 100644
index 0000000000..b5335d5270
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.ir.txt
@@ -0,0 +1,130 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (89:5,1 [102] Await.cshtml)
+ IntermediateToken - (89:5,1 [4] Await.cshtml) - Html - \n\n
+ IntermediateToken - (93:7,0 [9] Await.cshtml) - Html - <section>
+ IntermediateToken - (102:7,9 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (108:8,4 [4] Await.cshtml) - Html - <h1>
+ IntermediateToken - (112:8,8 [34] Await.cshtml) - Html - Basic Asynchronous Expression Test
+ IntermediateToken - (146:8,42 [5] Await.cshtml) - Html - </h1>
+ IntermediateToken - (151:8,47 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (157:9,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (160:9,7 [31] Await.cshtml) - Html - Basic Asynchronous Expression:
+ CSharpExpression - (192:9,39 [11] Await.cshtml)
+ IntermediateToken - (192:9,39 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (203:9,50 [42] Await.cshtml)
+ IntermediateToken - (203:9,50 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (207:9,54 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (213:10,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (216:10,7 [29] Await.cshtml) - Html - Basic Asynchronous Template:
+ CSharpExpression - (247:10,38 [11] Await.cshtml)
+ IntermediateToken - (247:10,38 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (259:10,50 [43] Await.cshtml)
+ IntermediateToken - (259:10,50 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (263:10,54 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (269:11,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (272:11,7 [30] Await.cshtml) - Html - Basic Asynchronous Statement:
+ CSharpCode - (304:11,39 [14] Await.cshtml)
+ IntermediateToken - (304:11,39 [14] Await.cshtml) - CSharp - await Foo();
+ HtmlContent - (319:11,54 [50] Await.cshtml)
+ IntermediateToken - (319:11,54 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (323:11,58 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (329:12,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (332:12,7 [37] Await.cshtml) - Html - Basic Asynchronous Statement Nested:
+ CSharpCode - (371:12,46 [1] Await.cshtml)
+ IntermediateToken - (371:12,46 [1] Await.cshtml) - CSharp -
+ HtmlContent - (372:12,47 [3] Await.cshtml)
+ IntermediateToken - (372:12,47 [3] Await.cshtml) - Html - <b>
+ CSharpExpression - (376:12,51 [11] Await.cshtml)
+ IntermediateToken - (376:12,51 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (387:12,62 [4] Await.cshtml)
+ IntermediateToken - (387:12,62 [4] Await.cshtml) - Html - </b>
+ CSharpCode - (391:12,66 [1] Await.cshtml)
+ IntermediateToken - (391:12,66 [1] Await.cshtml) - CSharp -
+ HtmlContent - (393:12,68 [54] Await.cshtml)
+ IntermediateToken - (393:12,68 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (397:12,72 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (403:13,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (406:13,7 [41] Await.cshtml) - Html - Basic Incomplete Asynchronous Statement:
+ CSharpExpression - (448:13,49 [5] Await.cshtml)
+ IntermediateToken - (448:13,49 [5] Await.cshtml) - CSharp - await
+ HtmlContent - (453:13,54 [124] Await.cshtml)
+ IntermediateToken - (453:13,54 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (457:13,58 [2] Await.cshtml) - Html - \n
+ IntermediateToken - (459:14,0 [10] Await.cshtml) - Html - </section>
+ IntermediateToken - (469:14,10 [4] Await.cshtml) - Html - \n\n
+ IntermediateToken - (473:16,0 [9] Await.cshtml) - Html - <section>
+ IntermediateToken - (482:16,9 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (488:17,4 [4] Await.cshtml) - Html - <h1>
+ IntermediateToken - (492:17,8 [37] Await.cshtml) - Html - Advanced Asynchronous Expression Test
+ IntermediateToken - (529:17,45 [5] Await.cshtml) - Html - </h1>
+ IntermediateToken - (534:17,50 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (540:18,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (543:18,7 [34] Await.cshtml) - Html - Advanced Asynchronous Expression:
+ CSharpExpression - (578:18,42 [15] Await.cshtml)
+ IntermediateToken - (578:18,42 [15] Await.cshtml) - CSharp - await Foo(1, 2)
+ HtmlContent - (593:18,57 [56] Await.cshtml)
+ IntermediateToken - (593:18,57 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (597:18,61 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (603:19,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (606:19,7 [43] Await.cshtml) - Html - Advanced Asynchronous Expression Extended:
+ CSharpExpression - (650:19,51 [19] Await.cshtml)
+ IntermediateToken - (650:19,51 [19] Await.cshtml) - CSharp - await Foo.Bar(1, 2)
+ HtmlContent - (669:19,70 [45] Await.cshtml)
+ IntermediateToken - (669:19,70 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (673:19,74 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (679:20,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (682:20,7 [32] Await.cshtml) - Html - Advanced Asynchronous Template:
+ CSharpExpression - (716:20,41 [22] Await.cshtml)
+ IntermediateToken - (716:20,41 [22] Await.cshtml) - CSharp - await Foo("bob", true)
+ HtmlContent - (739:20,64 [46] Await.cshtml)
+ IntermediateToken - (739:20,64 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (743:20,68 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (749:21,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (752:21,7 [33] Await.cshtml) - Html - Advanced Asynchronous Statement:
+ CSharpCode - (787:21,42 [39] Await.cshtml)
+ IntermediateToken - (787:21,42 [39] Await.cshtml) - CSharp - await Foo(something, hello: "world");
+ HtmlContent - (827:21,82 [55] Await.cshtml)
+ IntermediateToken - (827:21,82 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (831:21,86 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (837:22,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (840:22,7 [42] Await.cshtml) - Html - Advanced Asynchronous Statement Extended:
+ CSharpCode - (884:22,51 [21] Await.cshtml)
+ IntermediateToken - (884:22,51 [21] Await.cshtml) - CSharp - await Foo.Bar(1, 2)
+ HtmlContent - (906:22,73 [53] Await.cshtml)
+ IntermediateToken - (906:22,73 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (910:22,77 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (916:23,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (919:23,7 [40] Await.cshtml) - Html - Advanced Asynchronous Statement Nested:
+ CSharpCode - (961:23,49 [1] Await.cshtml)
+ IntermediateToken - (961:23,49 [1] Await.cshtml) - CSharp -
+ HtmlContent - (962:23,50 [3] Await.cshtml)
+ IntermediateToken - (962:23,50 [3] Await.cshtml) - Html - <b>
+ CSharpExpression - (966:23,54 [27] Await.cshtml)
+ IntermediateToken - (966:23,54 [27] Await.cshtml) - CSharp - await Foo(boolValue: false)
+ HtmlContent - (993:23,81 [4] Await.cshtml)
+ IntermediateToken - (993:23,81 [4] Await.cshtml) - Html - </b>
+ CSharpCode - (997:23,85 [1] Await.cshtml)
+ IntermediateToken - (997:23,85 [1] Await.cshtml) - CSharp -
+ HtmlContent - (999:23,87 [57] Await.cshtml)
+ IntermediateToken - (999:23,87 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (1003:23,91 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (1009:24,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (1012:24,7 [44] Await.cshtml) - Html - Advanced Incomplete Asynchronous Statement:
+ CSharpExpression - (1057:24,52 [19] Await.cshtml)
+ IntermediateToken - (1057:24,52 [19] Await.cshtml) - CSharp - await ("wrrronggg")
+ HtmlContent - (1076:24,71 [16] Await.cshtml)
+ IntermediateToken - (1076:24,71 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (1080:24,75 [2] Await.cshtml) - Html - \n
+ IntermediateToken - (1082:25,0 [10] Await.cshtml) - Html - </section>
+ CSharpCode - (12:0,12 [76] Await.cshtml)
+ IntermediateToken - (12:0,12 [76] Await.cshtml) - CSharp - \n public async Task<string> Foo()\n {\n return "Bar";\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.mappings.txt
new file mode 100644
index 0000000000..739f6092e2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_DesignTime.mappings.txt
@@ -0,0 +1,95 @@
+Source Location: (192:9,39 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo()|
+Generated Location: (749:18,39 [11] )
+|await Foo()|
+
+Source Location: (247:10,38 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo()|
+Generated Location: (914:23,38 [11] )
+|await Foo()|
+
+Source Location: (304:11,39 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| await Foo(); |
+Generated Location: (1080:28,39 [14] )
+| await Foo(); |
+
+Source Location: (371:12,46 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| |
+Generated Location: (1185:32,58 [1] )
+| |
+
+Source Location: (376:12,51 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo()|
+Generated Location: (1321:34,51 [11] )
+|await Foo()|
+
+Source Location: (391:12,66 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| |
+Generated Location: (1444:38,78 [1] )
+| |
+
+Source Location: (448:13,49 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await|
+Generated Location: (1578:40,49 [5] )
+|await|
+
+Source Location: (578:18,42 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo(1, 2)|
+Generated Location: (1741:45,42 [15] )
+|await Foo(1, 2)|
+
+Source Location: (650:19,51 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo.Bar(1, 2)|
+Generated Location: (1923:50,51 [19] )
+|await Foo.Bar(1, 2)|
+
+Source Location: (716:20,41 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo("bob", true)|
+Generated Location: (2099:55,41 [22] )
+|await Foo("bob", true)|
+
+Source Location: (787:21,42 [39] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| await Foo(something, hello: "world"); |
+Generated Location: (2279:60,42 [39] )
+| await Foo(something, hello: "world"); |
+
+Source Location: (884:22,51 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| await Foo.Bar(1, 2) |
+Generated Location: (2484:65,51 [21] )
+| await Foo.Bar(1, 2) |
+
+Source Location: (961:23,49 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| |
+Generated Location: (2599:69,61 [1] )
+| |
+
+Source Location: (966:23,54 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await Foo(boolValue: false)|
+Generated Location: (2738:71,54 [27] )
+|await Foo(boolValue: false)|
+
+Source Location: (997:23,85 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+| |
+Generated Location: (2896:75,97 [1] )
+| |
+
+Source Location: (1057:24,52 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|await ("wrrronggg")|
+Generated Location: (3033:77,52 [19] )
+|await ("wrrronggg")|
+
+Source Location: (12:0,12 [76] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml)
+|
+ public async Task<string> Foo()
+ {
+ return "Bar";
+ }
+|
+Generated Location: (3228:84,12 [76] )
+|
+ public async Task<string> Foo()
+ {
+ return "Bar";
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.codegen.cs
new file mode 100644
index 0000000000..e7c1ed3c55
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.codegen.cs
@@ -0,0 +1,104 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5a02c3ec89081f6e0a8f4810e127eed40467c358"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5a02c3ec89081f6e0a8f4810e127eed40467c358", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<section>\r\n <h1>Basic Asynchronous Expression Test</h1>\r\n <p>Basic Asynchronous Expression: ");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo());
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Basic Asynchronous Template: ");
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo());
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Basic Asynchronous Statement: ");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo();
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Basic Asynchronous Statement Nested: ");
+ WriteLiteral(" <b>");
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo());
+
+#line default
+#line hidden
+ WriteLiteral("</b> ");
+ WriteLiteral("</p>\r\n <p>Basic Incomplete Asynchronous Statement: ");
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n</section>\r\n\r\n<section>\r\n <h1>Advanced Asynchronous Expression Test</h1>\r\n <p>Advanced Asynchronous Expression: ");
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo(1, 2));
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Advanced Asynchronous Expression Extended: ");
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo.Bar(1, 2));
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Advanced Asynchronous Template: ");
+#line 21 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo("bob", true));
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Advanced Asynchronous Statement: ");
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo(something, hello: "world");
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Advanced Asynchronous Statement Extended: ");
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ await Foo.Bar(1, 2)
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n <p>Advanced Asynchronous Statement Nested: ");
+ WriteLiteral(" <b>");
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await Foo(boolValue: false));
+
+#line default
+#line hidden
+ WriteLiteral("</b> ");
+ WriteLiteral("</p>\r\n <p>Advanced Incomplete Asynchronous Statement: ");
+#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+ Write(await ("wrrronggg"));
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n</section>");
+ }
+ #pragma warning restore 1998
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await.cshtml"
+
+ public async Task<string> Foo()
+ {
+ return "Bar";
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.ir.txt
new file mode 100644
index 0000000000..1890add00a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Await_Runtime.ir.txt
@@ -0,0 +1,125 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Await_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (91:6,0 [100] Await.cshtml)
+ IntermediateToken - (91:6,0 [2] Await.cshtml) - Html - \n
+ IntermediateToken - (93:7,0 [9] Await.cshtml) - Html - <section>
+ IntermediateToken - (102:7,9 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (108:8,4 [4] Await.cshtml) - Html - <h1>
+ IntermediateToken - (112:8,8 [34] Await.cshtml) - Html - Basic Asynchronous Expression Test
+ IntermediateToken - (146:8,42 [5] Await.cshtml) - Html - </h1>
+ IntermediateToken - (151:8,47 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (157:9,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (160:9,7 [31] Await.cshtml) - Html - Basic Asynchronous Expression:
+ CSharpExpression - (192:9,39 [11] Await.cshtml)
+ IntermediateToken - (192:9,39 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (203:9,50 [42] Await.cshtml)
+ IntermediateToken - (203:9,50 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (207:9,54 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (213:10,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (216:10,7 [29] Await.cshtml) - Html - Basic Asynchronous Template:
+ CSharpExpression - (247:10,38 [11] Await.cshtml)
+ IntermediateToken - (247:10,38 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (259:10,50 [43] Await.cshtml)
+ IntermediateToken - (259:10,50 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (263:10,54 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (269:11,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (272:11,7 [30] Await.cshtml) - Html - Basic Asynchronous Statement:
+ CSharpCode - (304:11,39 [14] Await.cshtml)
+ IntermediateToken - (304:11,39 [14] Await.cshtml) - CSharp - await Foo();
+ HtmlContent - (319:11,54 [50] Await.cshtml)
+ IntermediateToken - (319:11,54 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (323:11,58 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (329:12,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (332:12,7 [37] Await.cshtml) - Html - Basic Asynchronous Statement Nested:
+ HtmlContent - (371:12,46 [4] Await.cshtml)
+ IntermediateToken - (371:12,46 [1] Await.cshtml) - Html -
+ IntermediateToken - (372:12,47 [3] Await.cshtml) - Html - <b>
+ CSharpExpression - (376:12,51 [11] Await.cshtml)
+ IntermediateToken - (376:12,51 [11] Await.cshtml) - CSharp - await Foo()
+ HtmlContent - (387:12,62 [5] Await.cshtml)
+ IntermediateToken - (387:12,62 [4] Await.cshtml) - Html - </b>
+ IntermediateToken - (391:12,66 [1] Await.cshtml) - Html -
+ CSharpCode - (392:12,67 [0] Await.cshtml)
+ IntermediateToken - (392:12,67 [0] Await.cshtml) - CSharp -
+ HtmlContent - (393:12,68 [54] Await.cshtml)
+ IntermediateToken - (393:12,68 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (397:12,72 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (403:13,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (406:13,7 [41] Await.cshtml) - Html - Basic Incomplete Asynchronous Statement:
+ CSharpExpression - (448:13,49 [5] Await.cshtml)
+ IntermediateToken - (448:13,49 [5] Await.cshtml) - CSharp - await
+ HtmlContent - (453:13,54 [124] Await.cshtml)
+ IntermediateToken - (453:13,54 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (457:13,58 [2] Await.cshtml) - Html - \n
+ IntermediateToken - (459:14,0 [10] Await.cshtml) - Html - </section>
+ IntermediateToken - (469:14,10 [4] Await.cshtml) - Html - \n\n
+ IntermediateToken - (473:16,0 [9] Await.cshtml) - Html - <section>
+ IntermediateToken - (482:16,9 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (488:17,4 [4] Await.cshtml) - Html - <h1>
+ IntermediateToken - (492:17,8 [37] Await.cshtml) - Html - Advanced Asynchronous Expression Test
+ IntermediateToken - (529:17,45 [5] Await.cshtml) - Html - </h1>
+ IntermediateToken - (534:17,50 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (540:18,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (543:18,7 [34] Await.cshtml) - Html - Advanced Asynchronous Expression:
+ CSharpExpression - (578:18,42 [15] Await.cshtml)
+ IntermediateToken - (578:18,42 [15] Await.cshtml) - CSharp - await Foo(1, 2)
+ HtmlContent - (593:18,57 [56] Await.cshtml)
+ IntermediateToken - (593:18,57 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (597:18,61 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (603:19,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (606:19,7 [43] Await.cshtml) - Html - Advanced Asynchronous Expression Extended:
+ CSharpExpression - (650:19,51 [19] Await.cshtml)
+ IntermediateToken - (650:19,51 [19] Await.cshtml) - CSharp - await Foo.Bar(1, 2)
+ HtmlContent - (669:19,70 [45] Await.cshtml)
+ IntermediateToken - (669:19,70 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (673:19,74 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (679:20,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (682:20,7 [32] Await.cshtml) - Html - Advanced Asynchronous Template:
+ CSharpExpression - (716:20,41 [22] Await.cshtml)
+ IntermediateToken - (716:20,41 [22] Await.cshtml) - CSharp - await Foo("bob", true)
+ HtmlContent - (739:20,64 [46] Await.cshtml)
+ IntermediateToken - (739:20,64 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (743:20,68 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (749:21,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (752:21,7 [33] Await.cshtml) - Html - Advanced Asynchronous Statement:
+ CSharpCode - (787:21,42 [39] Await.cshtml)
+ IntermediateToken - (787:21,42 [39] Await.cshtml) - CSharp - await Foo(something, hello: "world");
+ HtmlContent - (827:21,82 [55] Await.cshtml)
+ IntermediateToken - (827:21,82 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (831:21,86 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (837:22,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (840:22,7 [42] Await.cshtml) - Html - Advanced Asynchronous Statement Extended:
+ CSharpCode - (884:22,51 [21] Await.cshtml)
+ IntermediateToken - (884:22,51 [21] Await.cshtml) - CSharp - await Foo.Bar(1, 2)
+ HtmlContent - (906:22,73 [53] Await.cshtml)
+ IntermediateToken - (906:22,73 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (910:22,77 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (916:23,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (919:23,7 [40] Await.cshtml) - Html - Advanced Asynchronous Statement Nested:
+ HtmlContent - (961:23,49 [4] Await.cshtml)
+ IntermediateToken - (961:23,49 [1] Await.cshtml) - Html -
+ IntermediateToken - (962:23,50 [3] Await.cshtml) - Html - <b>
+ CSharpExpression - (966:23,54 [27] Await.cshtml)
+ IntermediateToken - (966:23,54 [27] Await.cshtml) - CSharp - await Foo(boolValue: false)
+ HtmlContent - (993:23,81 [5] Await.cshtml)
+ IntermediateToken - (993:23,81 [4] Await.cshtml) - Html - </b>
+ IntermediateToken - (997:23,85 [1] Await.cshtml) - Html -
+ CSharpCode - (998:23,86 [0] Await.cshtml)
+ IntermediateToken - (998:23,86 [0] Await.cshtml) - CSharp -
+ HtmlContent - (999:23,87 [57] Await.cshtml)
+ IntermediateToken - (999:23,87 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (1003:23,91 [6] Await.cshtml) - Html - \n
+ IntermediateToken - (1009:24,4 [3] Await.cshtml) - Html - <p>
+ IntermediateToken - (1012:24,7 [44] Await.cshtml) - Html - Advanced Incomplete Asynchronous Statement:
+ CSharpExpression - (1057:24,52 [19] Await.cshtml)
+ IntermediateToken - (1057:24,52 [19] Await.cshtml) - CSharp - await ("wrrronggg")
+ HtmlContent - (1076:24,71 [16] Await.cshtml)
+ IntermediateToken - (1076:24,71 [4] Await.cshtml) - Html - </p>
+ IntermediateToken - (1080:24,75 [2] Await.cshtml) - Html - \n
+ IntermediateToken - (1082:25,0 [10] Await.cshtml) - Html - </section>
+ CSharpCode - (12:0,12 [76] Await.cshtml)
+ IntermediateToken - (12:0,12 [76] Await.cshtml) - CSharp - \n public async Task<string> Foo()\n {\n return "Bar";\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml
new file mode 100644
index 0000000000..bf4d925aea
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml
@@ -0,0 +1 @@
+<p>Hi there!</p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.codegen.cs
new file mode 100644
index 0000000000..b6226ce38a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.codegen.cs
@@ -0,0 +1,37 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
+using System.Globalization;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
+using System.ComponentModel;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml"
+using System.Text;
+
+#line default
+#line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_DesignTime : Hello
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.ir.txt
new file mode 100644
index 0000000000..fab53bac03
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.ir.txt
@@ -0,0 +1,20 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ UsingDirective - (1:0,1 [26] BasicImports_Imports0.cshtml) - System.Globalization
+ UsingDirective - (30:1,1 [27] BasicImports_Imports0.cshtml) - System.ComponentModel
+ UsingDirective - (23:1,1 [18] BasicImports_Imports1.cshtml) - System.Text
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_DesignTime - Hello -
+ DesignTimeDirective -
+ DirectiveToken - (69:2,10 [5] BasicImports_Imports0.cshtml) - Hello
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] BasicImports.cshtml)
+ IntermediateToken - (0:0,0 [3] BasicImports.cshtml) - Html - <p>
+ IntermediateToken - (3:0,3 [9] BasicImports.cshtml) - Html - Hi there!
+ IntermediateToken - (12:0,12 [4] BasicImports.cshtml) - Html - </p>
+ IntermediateToken - (16:0,16 [2] BasicImports.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.mappings.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_DesignTime.mappings.txt
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml
new file mode 100644
index 0000000000..b71f569138
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml
@@ -0,0 +1,5 @@
+@using System.Globalization
+@using System.ComponentModel
+@inherits Hello
+@("And also this")
+<p>This will get ignored</p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml
new file mode 100644
index 0000000000..bac4a38695
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml
@@ -0,0 +1,2 @@
+@section ignored { }
+@using System.Text;
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.codegen.cs
new file mode 100644
index 0000000000..ed71849611
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.codegen.cs
@@ -0,0 +1,36 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d5e5d28c0c504a7b0c5207a5230a5b7327ce5e09"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
+using System.Globalization;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml"
+using System.ComponentModel;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml"
+using System.Text;
+
+#line default
+#line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d5e5d28c0c504a7b0c5207a5230a5b7327ce5e09", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports.cshtml")]
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"39c22940acc420eb6d46b6ff85ef6d5a2ab35fa1", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports0.cshtml")]
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"ede697b6fb90aac312d589ae96a93289cdeb506f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Imports1.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime : Hello
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<p>Hi there!</p>\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.ir.txt
new file mode 100644
index 0000000000..014ca50451
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicImports_Runtime.ir.txt
@@ -0,0 +1,16 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ UsingDirective - (1:0,1 [28] BasicImports_Imports0.cshtml) - System.Globalization
+ UsingDirective - (30:1,1 [29] BasicImports_Imports0.cshtml) - System.ComponentModel
+ UsingDirective - (23:1,1 [20] BasicImports_Imports1.cshtml) - System.Text
+ RazorSourceChecksumAttribute -
+ RazorSourceChecksumAttribute -
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicImports_Runtime - Hello -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] BasicImports.cshtml)
+ IntermediateToken - (0:0,0 [3] BasicImports.cshtml) - Html - <p>
+ IntermediateToken - (3:0,3 [9] BasicImports.cshtml) - Html - Hi there!
+ IntermediateToken - (12:0,12 [4] BasicImports.cshtml) - Html - </p>
+ IntermediateToken - (16:0,16 [2] BasicImports.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml
new file mode 100644
index 0000000000..b58b6b44ff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml
@@ -0,0 +1,9 @@
+@addTagHelper "*, TestAssembly"
+
+<div data-animation="fade" class="randomNonTagHelperAttribute">
+ <p class="Hello World" data-delay="1000">
+ <p data="-delay1000"></p>
+ <input data-interval="2000 + @ViewBag.DefaultInterval + 1" type="text">
+ <input type="checkbox" checked="true"/>
+ </p>
+</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ee78430716
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,49 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml"
+ __o = ViewBag.DefaultInterval;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = "text";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "checkbox";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..38d793eaeb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,84 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] BasicTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [73] BasicTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] BasicTagHelpers.cshtml) - Html - \n\n
+ IntermediateToken - (35:2,0 [4] BasicTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (39:2,4 [17] BasicTagHelpers.cshtml) - Html - data-animation="
+ IntermediateToken - (56:2,21 [4] BasicTagHelpers.cshtml) - Html - fade
+ IntermediateToken - (60:2,25 [1] BasicTagHelpers.cshtml) - Html - "
+ IntermediateToken - (61:2,26 [36] BasicTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (97:2,62 [1] BasicTagHelpers.cshtml) - Html - >
+ IntermediateToken - (98:2,63 [6] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (104:3,4 [216] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (145:3,45 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (145:3,45 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (155:4,8 [25] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - data - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (164:4,17 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (164:4,17 [10] BasicTagHelpers.cshtml) - Html - -delay1000
+ DefaultTagHelperExecute -
+ HtmlContent - (180:4,33 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (180:4,33 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (190:5,8 [71] BasicTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - data-interval - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (212:5,30 [7] BasicTagHelpers.cshtml)
+ IntermediateToken - (212:5,30 [7] BasicTagHelpers.cshtml) - Html - 2000 +
+ CSharpExpression - (220:5,38 [23] BasicTagHelpers.cshtml)
+ IntermediateToken - (220:5,38 [23] BasicTagHelpers.cshtml) - CSharp - ViewBag.DefaultInterval
+ HtmlContent - (243:5,61 [4] BasicTagHelpers.cshtml)
+ IntermediateToken - (243:5,61 [4] BasicTagHelpers.cshtml) - Html - + 1
+ DefaultTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (255:5,73 [4] BasicTagHelpers.cshtml)
+ IntermediateToken - (255:5,73 [4] BasicTagHelpers.cshtml) - Html - text
+ DefaultTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (255:5,73 [4] BasicTagHelpers.cshtml)
+ IntermediateToken - (255:5,73 [4] BasicTagHelpers.cshtml) - Html - text
+ DefaultTagHelperExecute -
+ HtmlContent - (261:5,79 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (261:5,79 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (271:6,8 [39] BasicTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (284:6,21 [8] BasicTagHelpers.cshtml)
+ IntermediateToken - (284:6,21 [8] BasicTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (284:6,21 [8] BasicTagHelpers.cshtml)
+ IntermediateToken - (284:6,21 [8] BasicTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (303:6,40 [4] BasicTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (303:6,40 [4] BasicTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (310:6,47 [6] BasicTagHelpers.cshtml)
+ IntermediateToken - (310:6,47 [6] BasicTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (114:3,14 [11] BasicTagHelpers.cshtml)
+ IntermediateToken - (114:3,14 [11] BasicTagHelpers.cshtml) - Html - Hello World
+ DefaultTagHelperHtmlAttribute - - data-delay - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (139:3,39 [4] BasicTagHelpers.cshtml)
+ IntermediateToken - (139:3,39 [4] BasicTagHelpers.cshtml) - Html - 1000
+ DefaultTagHelperExecute -
+ HtmlContent - (320:7,8 [8] BasicTagHelpers.cshtml)
+ IntermediateToken - (320:7,8 [2] BasicTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (322:8,0 [6] BasicTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..6eb05c5160
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (673:13,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (220:5,38 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
+|ViewBag.DefaultInterval|
+Generated Location: (1439:28,38 [23] )
+|ViewBag.DefaultInterval|
+
+Source Location: (303:6,40 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml)
+|true|
+Generated Location: (2137:39,42 [4] )
+|true|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml
new file mode 100644
index 0000000000..089363600c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml
@@ -0,0 +1,10 @@
+@tagHelperPrefix "THS"
+@addTagHelper "*, TestAssembly"
+
+<THSdiv class="randomNonTagHelperAttribute">
+ <THSp class="Hello World">
+ <p></p>
+ <input type="text">
+ <THSinput type="checkbox" checked="true">
+ </THSp>
+</THSdiv> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.codegen.cs
new file mode 100644
index 0000000000..6322f77a95
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.codegen.cs
@@ -0,0 +1,43 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "THS";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "checkbox";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.ir.txt
new file mode 100644
index 0000000000..650d25e202
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.ir.txt
@@ -0,0 +1,59 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (17:0,17 [5] BasicTagHelpers_Prefixed.cshtml) - "THS"
+ DirectiveToken - (38:1,14 [17] BasicTagHelpers_Prefixed.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (22:0,22 [2] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (22:0,22 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ HtmlContent - (55:1,31 [54] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (55:1,31 [4] BasicTagHelpers_Prefixed.cshtml) - Html - \n\n
+ IntermediateToken - (59:3,0 [7] BasicTagHelpers_Prefixed.cshtml) - Html - <THSdiv
+ IntermediateToken - (66:3,7 [36] BasicTagHelpers_Prefixed.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (102:3,43 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
+ IntermediateToken - (103:3,44 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ TagHelper - (109:4,4 [136] BasicTagHelpers_Prefixed.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (135:4,30 [56] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (135:4,30 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (145:5,8 [3] BasicTagHelpers_Prefixed.cshtml) - Html - <p>
+ IntermediateToken - (148:5,11 [4] BasicTagHelpers_Prefixed.cshtml) - Html - </p>
+ IntermediateToken - (152:5,15 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (162:6,8 [6] BasicTagHelpers_Prefixed.cshtml) - Html - <input
+ IntermediateToken - (168:6,14 [12] BasicTagHelpers_Prefixed.cshtml) - Html - type="text"
+ IntermediateToken - (180:6,26 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
+ IntermediateToken - (181:6,27 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ TagHelper - (191:7,8 [41] BasicTagHelpers_Prefixed.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (122:4,17 [11] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (122:4,17 [11] BasicTagHelpers_Prefixed.cshtml) - Html - Hello World
+ DefaultTagHelperExecute -
+ HtmlContent - (245:8,11 [11] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (245:8,11 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (247:9,0 [9] BasicTagHelpers_Prefixed.cshtml) - Html - </THSdiv>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.mappings.txt
new file mode 100644
index 0000000000..7c5ad4ca43
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_DesignTime.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (17:0,17 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
+|"THS"|
+Generated Location: (682:13,37 [5] )
+|"THS"|
+
+Source Location: (38:1,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
+|"*, TestAssembly"|
+Generated Location: (787:17,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (226:7,43 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml)
+|true|
+Generated Location: (1624:33,43 [4] )
+|true|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.codegen.cs
new file mode 100644
index 0000000000..af5da65ec3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.codegen.cs
@@ -0,0 +1,82 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b7372519d2a9b45537aba0e7d34309526d3014c3"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"b7372519d2a9b45537aba0e7d34309526d3014c3", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<THSdiv class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n <p></p>\r\n <input type=\"text\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</THSdiv>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.ir.txt
new file mode 100644
index 0000000000..f78f3256b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Prefixed_Runtime.ir.txt
@@ -0,0 +1,46 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Prefixed_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (57:2,0 [52] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (57:2,0 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (59:3,0 [7] BasicTagHelpers_Prefixed.cshtml) - Html - <THSdiv
+ IntermediateToken - (66:3,7 [36] BasicTagHelpers_Prefixed.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (102:3,43 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
+ IntermediateToken - (103:3,44 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ TagHelper - (109:4,4 [136] BasicTagHelpers_Prefixed.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (135:4,30 [56] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (135:4,30 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (145:5,8 [3] BasicTagHelpers_Prefixed.cshtml) - Html - <p>
+ IntermediateToken - (148:5,11 [4] BasicTagHelpers_Prefixed.cshtml) - Html - </p>
+ IntermediateToken - (152:5,15 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (162:6,8 [6] BasicTagHelpers_Prefixed.cshtml) - Html - <input
+ IntermediateToken - (168:6,14 [12] BasicTagHelpers_Prefixed.cshtml) - Html - type="text"
+ IntermediateToken - (180:6,26 [1] BasicTagHelpers_Prefixed.cshtml) - Html - >
+ IntermediateToken - (181:6,27 [10] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ TagHelper - (191:7,8 [41] BasicTagHelpers_Prefixed.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (207:7,24 [8] BasicTagHelpers_Prefixed.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (226:7,43 [4] BasicTagHelpers_Prefixed.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (232:7,49 [6] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (245:8,11 [11] BasicTagHelpers_Prefixed.cshtml)
+ IntermediateToken - (245:8,11 [2] BasicTagHelpers_Prefixed.cshtml) - Html - \n
+ IntermediateToken - (247:9,0 [9] BasicTagHelpers_Prefixed.cshtml) - Html - </THSdiv>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml
new file mode 100644
index 0000000000..56ac77231a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml
@@ -0,0 +1,10 @@
+@addTagHelper "*, TestAssembly"
+@removeTagHelper "doesntmatter, nice"
+
+<div class="randomNonTagHelperAttribute">
+ <p class="Hello World">
+ <p></p>
+ <input type="text" />
+ <input type="checkbox" checked="true"/>
+ </p>
+</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.codegen.cs
new file mode 100644
index 0000000000..c60b56f3df
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.codegen.cs
@@ -0,0 +1,115 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2e30c5c6e01a148ccf4ed5dd4a81939641312a17"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_RemoveTagHelper_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2e30c5c6e01a148ccf4ed5dd4a81939641312a17", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_RemoveTagHelper_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</div>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.ir.txt
new file mode 100644
index 0000000000..ef78c52e75
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_RemoveTagHelper_Runtime.ir.txt
@@ -0,0 +1,55 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_RemoveTagHelper_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (72:2,0 [49] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (72:2,0 [2] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ IntermediateToken - (74:3,0 [4] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - <div
+ IntermediateToken - (78:3,4 [36] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (114:3,40 [1] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - >
+ IntermediateToken - (115:3,41 [6] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ TagHelper - (121:4,4 [130] BasicTagHelpers_RemoveTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (144:4,27 [10] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (144:4,27 [10] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ TagHelper - (154:5,8 [7] BasicTagHelpers_RemoveTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (161:5,15 [10] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (161:5,15 [10] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ TagHelper - (171:6,8 [21] BasicTagHelpers_RemoveTagHelper.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (184:6,21 [4] BasicTagHelpers_RemoveTagHelper.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (184:6,21 [4] BasicTagHelpers_RemoveTagHelper.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperExecute -
+ HtmlContent - (192:6,29 [10] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (192:6,29 [10] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ TagHelper - (202:7,8 [39] BasicTagHelpers_RemoveTagHelper.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (215:7,21 [8] BasicTagHelpers_RemoveTagHelper.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperProperty - (215:7,21 [8] BasicTagHelpers_RemoveTagHelper.cshtml) - __tagHelperAttribute_1 - type - Type
+ DefaultTagHelperProperty - (234:7,40 [4] BasicTagHelpers_RemoveTagHelper.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (234:7,40 [4] BasicTagHelpers_RemoveTagHelper.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (241:7,47 [6] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (241:7,47 [6] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ HtmlContent - (251:8,8 [8] BasicTagHelpers_RemoveTagHelper.cshtml)
+ IntermediateToken - (251:8,8 [2] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - \n
+ IntermediateToken - (253:9,0 [6] BasicTagHelpers_RemoveTagHelper.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..ed7e3a7cbc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,129 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2775a5b97b6aa9fc7b162124fddb7400ec1e2472"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2775a5b97b6aa9fc7b162124fddb7400ec1e2472", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data", new global::Microsoft.AspNetCore.Html.HtmlString("-delay1000"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-delay", new global::Microsoft.AspNetCore.Html.HtmlString("1000"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<div data-animation=\"fade\" class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("2000 + ");
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml"
+ Write(ViewBag.DefaultInterval);
+
+#line default
+#line hidden
+ WriteLiteral(" + 1");
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("data-interval", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_2.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_2);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_2.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_2);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_4);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</div>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..ce7caef785
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/BasicTagHelpers_Runtime.ir.txt
@@ -0,0 +1,69 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_BasicTagHelpers_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - data - -delay1000 - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_2 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_4 - data-delay - 1000 - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [71] BasicTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] BasicTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (35:2,0 [4] BasicTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (39:2,4 [17] BasicTagHelpers.cshtml) - Html - data-animation="
+ IntermediateToken - (56:2,21 [4] BasicTagHelpers.cshtml) - Html - fade
+ IntermediateToken - (60:2,25 [1] BasicTagHelpers.cshtml) - Html - "
+ IntermediateToken - (61:2,26 [36] BasicTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (97:2,62 [1] BasicTagHelpers.cshtml) - Html - >
+ IntermediateToken - (98:2,63 [6] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (104:3,4 [216] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (145:3,45 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (145:3,45 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (155:4,8 [25] BasicTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (180:4,33 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (180:4,33 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (190:5,8 [71] BasicTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - data-interval - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (212:5,30 [7] BasicTagHelpers.cshtml)
+ IntermediateToken - (212:5,30 [7] BasicTagHelpers.cshtml) - Html - 2000 +
+ CSharpExpression - (220:5,38 [23] BasicTagHelpers.cshtml)
+ IntermediateToken - (220:5,38 [23] BasicTagHelpers.cshtml) - CSharp - ViewBag.DefaultInterval
+ HtmlContent - (243:5,61 [4] BasicTagHelpers.cshtml)
+ IntermediateToken - (243:5,61 [4] BasicTagHelpers.cshtml) - Html - + 1
+ PreallocatedTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperProperty - (255:5,73 [4] BasicTagHelpers.cshtml) - __tagHelperAttribute_1 - type - Type
+ DefaultTagHelperExecute -
+ HtmlContent - (261:5,79 [10] BasicTagHelpers.cshtml)
+ IntermediateToken - (261:5,79 [10] BasicTagHelpers.cshtml) - Html - \n
+ TagHelper - (271:6,8 [39] BasicTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - __tagHelperAttribute_2 - type - Type
+ PreallocatedTagHelperProperty - (284:6,21 [8] BasicTagHelpers.cshtml) - __tagHelperAttribute_2 - type - Type
+ DefaultTagHelperProperty - (303:6,40 [4] BasicTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (303:6,40 [4] BasicTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (310:6,47 [6] BasicTagHelpers.cshtml)
+ IntermediateToken - (310:6,47 [6] BasicTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_4
+ DefaultTagHelperExecute -
+ HtmlContent - (320:7,8 [8] BasicTagHelpers.cshtml)
+ IntermediateToken - (320:7,8 [2] BasicTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (322:8,0 [6] BasicTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml
new file mode 100644
index 0000000000..8d27de89cc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml
@@ -0,0 +1,37 @@
+@{
+ int i = 1;
+}
+
+@while(i <= 10) {
+ <p>Hello from C#, #@(i)</p>
+ i += 1;
+}
+
+@if(i == 11) {
+ <p>We wrote 10 lines!</p>
+}
+
+@switch(i) {
+ case 11:
+ <p>No really, we wrote 10 lines!</p>
+ break;
+ default:
+ <p>Actually, we didn't...</p>
+ break;
+}
+
+@for(int j = 1; j <= 10; j += 2) {
+ <p>Hello again from C#, #@(j)</p>
+}
+
+@try {
+ <p>That time, we wrote 5 lines!</p>
+} catch(Exception ex) {
+ <p>Oh no! An error occurred: @(ex.Message)</p>
+}
+
+<p>i is now @i</p>
+
+@lock(new object()) {
+ <p>This block is locked, for your security!</p>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.codegen.cs
new file mode 100644
index 0000000000..94c35ebdef
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.codegen.cs
@@ -0,0 +1,138 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+ int i = 1;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ while(i <= 10) {
+
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+ i += 1;
+}
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ if(i == 11) {
+
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ switch(i) {
+ case 11:
+
+
+#line default
+#line hidden
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+ break;
+ default:
+
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+ break;
+}
+
+#line default
+#line hidden
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+
+#line default
+#line hidden
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ __o = j;
+
+#line default
+#line hidden
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ try {
+
+
+#line default
+#line hidden
+#line 28 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+} catch(Exception ex) {
+
+
+#line default
+#line hidden
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ __o = ex.Message;
+
+#line default
+#line hidden
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ lock(new object()) {
+
+
+#line default
+#line hidden
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.ir.txt
new file mode 100644
index 0000000000..a6919538e6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.ir.txt
@@ -0,0 +1,101 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [18] Blocks.cshtml)
+ IntermediateToken - (2:0,2 [18] Blocks.cshtml) - CSharp - \n int i = 1;\n
+ HtmlContent - (23:3,0 [2] Blocks.cshtml)
+ IntermediateToken - (23:3,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (26:4,1 [22] Blocks.cshtml)
+ IntermediateToken - (26:4,1 [22] Blocks.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (48:5,4 [19] Blocks.cshtml)
+ IntermediateToken - (48:5,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (51:5,7 [16] Blocks.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:5,25 [1] Blocks.cshtml)
+ IntermediateToken - (69:5,25 [1] Blocks.cshtml) - CSharp - i
+ HtmlContent - (71:5,27 [4] Blocks.cshtml)
+ IntermediateToken - (71:5,27 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (75:5,31 [16] Blocks.cshtml)
+ IntermediateToken - (75:5,31 [16] Blocks.cshtml) - CSharp - \n i += 1;\n}
+ HtmlContent - (91:7,1 [4] Blocks.cshtml)
+ IntermediateToken - (91:7,1 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (96:9,1 [19] Blocks.cshtml)
+ IntermediateToken - (96:9,1 [19] Blocks.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (115:10,4 [25] Blocks.cshtml)
+ IntermediateToken - (115:10,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (118:10,7 [18] Blocks.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (136:10,25 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (140:10,29 [3] Blocks.cshtml)
+ IntermediateToken - (140:10,29 [3] Blocks.cshtml) - CSharp - \n}
+ HtmlContent - (143:11,1 [4] Blocks.cshtml)
+ IntermediateToken - (143:11,1 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (148:13,1 [35] Blocks.cshtml)
+ IntermediateToken - (148:13,1 [35] Blocks.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (183:15,8 [36] Blocks.cshtml)
+ IntermediateToken - (183:15,8 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (186:15,11 [29] Blocks.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (215:15,40 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (219:15,44 [40] Blocks.cshtml)
+ IntermediateToken - (219:15,44 [40] Blocks.cshtml) - CSharp - \n break;\n default:\n
+ HtmlContent - (259:18,8 [29] Blocks.cshtml)
+ IntermediateToken - (259:18,8 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (262:18,11 [22] Blocks.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (284:18,33 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (288:18,37 [19] Blocks.cshtml)
+ IntermediateToken - (288:18,37 [19] Blocks.cshtml) - CSharp - \n break;\n}
+ HtmlContent - (307:20,1 [4] Blocks.cshtml)
+ IntermediateToken - (307:20,1 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (312:22,1 [39] Blocks.cshtml)
+ IntermediateToken - (312:22,1 [39] Blocks.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (351:23,4 [25] Blocks.cshtml)
+ IntermediateToken - (351:23,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (354:23,7 [22] Blocks.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (378:23,31 [1] Blocks.cshtml)
+ IntermediateToken - (378:23,31 [1] Blocks.cshtml) - CSharp - j
+ HtmlContent - (380:23,33 [4] Blocks.cshtml)
+ IntermediateToken - (380:23,33 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (384:23,37 [3] Blocks.cshtml)
+ IntermediateToken - (384:23,37 [3] Blocks.cshtml) - CSharp - \n}
+ HtmlContent - (387:24,1 [4] Blocks.cshtml)
+ IntermediateToken - (387:24,1 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (392:26,1 [11] Blocks.cshtml)
+ IntermediateToken - (392:26,1 [11] Blocks.cshtml) - CSharp - try {\n
+ HtmlContent - (403:27,4 [35] Blocks.cshtml)
+ IntermediateToken - (403:27,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (406:27,7 [28] Blocks.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (434:27,35 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (438:27,39 [31] Blocks.cshtml)
+ IntermediateToken - (438:27,39 [31] Blocks.cshtml) - CSharp - \n} catch(Exception ex) {\n
+ HtmlContent - (469:29,4 [29] Blocks.cshtml)
+ IntermediateToken - (469:29,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (472:29,7 [26] Blocks.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (500:29,35 [10] Blocks.cshtml)
+ IntermediateToken - (500:29,35 [10] Blocks.cshtml) - CSharp - ex.Message
+ HtmlContent - (511:29,46 [4] Blocks.cshtml)
+ IntermediateToken - (511:29,46 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (515:29,50 [3] Blocks.cshtml)
+ IntermediateToken - (515:29,50 [3] Blocks.cshtml) - CSharp - \n}
+ HtmlContent - (518:30,1 [16] Blocks.cshtml)
+ IntermediateToken - (518:30,1 [4] Blocks.cshtml) - Html - \n\n
+ IntermediateToken - (522:32,0 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (525:32,3 [9] Blocks.cshtml) - Html - i is now
+ CSharpExpression - (535:32,13 [1] Blocks.cshtml)
+ IntermediateToken - (535:32,13 [1] Blocks.cshtml) - CSharp - i
+ HtmlContent - (536:32,14 [8] Blocks.cshtml)
+ IntermediateToken - (536:32,14 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (540:32,18 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (545:34,1 [26] Blocks.cshtml)
+ IntermediateToken - (545:34,1 [26] Blocks.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (571:35,4 [47] Blocks.cshtml)
+ IntermediateToken - (571:35,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (574:35,7 [40] Blocks.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (614:35,47 [4] Blocks.cshtml) - Html - </p>
+ CSharpCode - (618:35,51 [3] Blocks.cshtml)
+ IntermediateToken - (618:35,51 [3] Blocks.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.mappings.txt
new file mode 100644
index 0000000000..abaf089f36
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_DesignTime.mappings.txt
@@ -0,0 +1,139 @@
+Source Location: (2:0,2 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+ int i = 1;
+|
+Generated Location: (713:18,2 [18] )
+|
+ int i = 1;
+|
+
+Source Location: (26:4,1 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|while(i <= 10) {
+ |
+Generated Location: (845:24,1 [22] )
+|while(i <= 10) {
+ |
+
+Source Location: (69:5,25 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|i|
+Generated Location: (1007:30,25 [1] )
+|i|
+
+Source Location: (75:5,31 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+ i += 1;
+}|
+Generated Location: (1155:35,31 [16] )
+|
+ i += 1;
+}|
+
+Source Location: (96:9,1 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|if(i == 11) {
+ |
+Generated Location: (1288:42,1 [19] )
+|if(i == 11) {
+ |
+
+Source Location: (140:10,29 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+}|
+Generated Location: (1452:48,29 [3] )
+|
+}|
+
+Source Location: (148:13,1 [35] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|switch(i) {
+ case 11:
+ |
+Generated Location: (1572:54,1 [35] )
+|switch(i) {
+ case 11:
+ |
+
+Source Location: (219:15,44 [40] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+ break;
+ default:
+ |
+Generated Location: (1767:61,44 [40] )
+|
+ break;
+ default:
+ |
+
+Source Location: (288:18,37 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+ break;
+}|
+Generated Location: (1960:69,37 [19] )
+|
+ break;
+}|
+
+Source Location: (312:22,1 [39] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|for(int j = 1; j <= 10; j += 2) {
+ |
+Generated Location: (2096:76,1 [39] )
+|for(int j = 1; j <= 10; j += 2) {
+ |
+
+Source Location: (378:23,31 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|j|
+Generated Location: (2282:82,31 [1] )
+|j|
+
+Source Location: (384:23,37 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+}|
+Generated Location: (2437:87,37 [3] )
+|
+}|
+
+Source Location: (392:26,1 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|try {
+ |
+Generated Location: (2557:93,1 [11] )
+|try {
+ |
+
+Source Location: (438:27,39 [31] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+} catch(Exception ex) {
+ |
+Generated Location: (2723:99,39 [31] )
+|
+} catch(Exception ex) {
+ |
+
+Source Location: (500:29,35 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|ex.Message|
+Generated Location: (2905:106,35 [10] )
+|ex.Message|
+
+Source Location: (515:29,50 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+}|
+Generated Location: (3082:111,50 [3] )
+|
+}|
+
+Source Location: (535:32,13 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|i|
+Generated Location: (3214:117,13 [1] )
+|i|
+
+Source Location: (545:34,1 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|lock(new object()) {
+ |
+Generated Location: (3333:122,1 [26] )
+|lock(new object()) {
+ |
+
+Source Location: (618:35,51 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml)
+|
+}|
+Generated Location: (3526:128,51 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.codegen.cs
new file mode 100644
index 0000000000..b139b936e7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.codegen.cs
@@ -0,0 +1,136 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "ed55fda2b7b0b96b044fc45da658dc062479924f"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"ed55fda2b7b0b96b044fc45da658dc062479924f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+
+ int i = 1;
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ while(i <= 10) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello from C#, #");
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ i += 1;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ if(i == 11) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>We wrote 10 lines!</p>\r\n");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ switch(i) {
+ case 11:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>No really, we wrote 10 lines!</p>\r\n");
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ break;
+ default:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Actually, we didn\'t...</p>\r\n");
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ break;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello again from C#, #");
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ Write(j);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ try {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>That time, we wrote 5 lines!</p>\r\n");
+#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+} catch(Exception ex) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Oh no! An error occurred: ");
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ Write(ex.Message);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 31 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n<p>i is now ");
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n\r\n");
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+ lock(new object()) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>This block is locked, for your security!</p>\r\n");
+#line 37 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.ir.txt
new file mode 100644
index 0000000000..9fa7984a1d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Blocks_Runtime.ir.txt
@@ -0,0 +1,112 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Blocks_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [18] Blocks.cshtml)
+ IntermediateToken - (2:0,2 [18] Blocks.cshtml) - CSharp - \n int i = 1;\n
+ HtmlContent - (23:3,0 [2] Blocks.cshtml)
+ IntermediateToken - (23:3,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (26:4,1 [18] Blocks.cshtml)
+ IntermediateToken - (26:4,1 [18] Blocks.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (44:5,0 [23] Blocks.cshtml)
+ IntermediateToken - (44:5,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (48:5,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (51:5,7 [16] Blocks.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:5,25 [1] Blocks.cshtml)
+ IntermediateToken - (69:5,25 [1] Blocks.cshtml) - CSharp - i
+ HtmlContent - (71:5,27 [6] Blocks.cshtml)
+ IntermediateToken - (71:5,27 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (75:5,31 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (77:6,0 [16] Blocks.cshtml)
+ IntermediateToken - (77:6,0 [16] Blocks.cshtml) - CSharp - i += 1;\n}\n
+ HtmlContent - (93:8,0 [2] Blocks.cshtml)
+ IntermediateToken - (93:8,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (96:9,1 [15] Blocks.cshtml)
+ IntermediateToken - (96:9,1 [15] Blocks.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (111:10,0 [31] Blocks.cshtml)
+ IntermediateToken - (111:10,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (115:10,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (118:10,7 [18] Blocks.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (136:10,25 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (140:10,29 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (142:11,0 [3] Blocks.cshtml)
+ IntermediateToken - (142:11,0 [3] Blocks.cshtml) - CSharp - }\n
+ HtmlContent - (145:12,0 [2] Blocks.cshtml)
+ IntermediateToken - (145:12,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (148:13,1 [27] Blocks.cshtml)
+ IntermediateToken - (148:13,1 [27] Blocks.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (175:15,0 [46] Blocks.cshtml)
+ IntermediateToken - (175:15,0 [8] Blocks.cshtml) - Html -
+ IntermediateToken - (183:15,8 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (186:15,11 [29] Blocks.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (215:15,40 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (219:15,44 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (221:16,0 [30] Blocks.cshtml)
+ IntermediateToken - (221:16,0 [30] Blocks.cshtml) - CSharp - break;\n default:\n
+ HtmlContent - (251:18,0 [39] Blocks.cshtml)
+ IntermediateToken - (251:18,0 [8] Blocks.cshtml) - Html -
+ IntermediateToken - (259:18,8 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (262:18,11 [22] Blocks.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (284:18,33 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (288:18,37 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (290:19,0 [19] Blocks.cshtml)
+ IntermediateToken - (290:19,0 [19] Blocks.cshtml) - CSharp - break;\n}\n
+ HtmlContent - (309:21,0 [2] Blocks.cshtml)
+ IntermediateToken - (309:21,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (312:22,1 [35] Blocks.cshtml)
+ IntermediateToken - (312:22,1 [35] Blocks.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (347:23,0 [29] Blocks.cshtml)
+ IntermediateToken - (347:23,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (351:23,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (354:23,7 [22] Blocks.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (378:23,31 [1] Blocks.cshtml)
+ IntermediateToken - (378:23,31 [1] Blocks.cshtml) - CSharp - j
+ HtmlContent - (380:23,33 [6] Blocks.cshtml)
+ IntermediateToken - (380:23,33 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (384:23,37 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (386:24,0 [3] Blocks.cshtml)
+ IntermediateToken - (386:24,0 [3] Blocks.cshtml) - CSharp - }\n
+ HtmlContent - (389:25,0 [2] Blocks.cshtml)
+ IntermediateToken - (389:25,0 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (392:26,1 [7] Blocks.cshtml)
+ IntermediateToken - (392:26,1 [7] Blocks.cshtml) - CSharp - try {\n
+ HtmlContent - (399:27,0 [41] Blocks.cshtml)
+ IntermediateToken - (399:27,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (403:27,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (406:27,7 [28] Blocks.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (434:27,35 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (438:27,39 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (440:28,0 [25] Blocks.cshtml)
+ IntermediateToken - (440:28,0 [25] Blocks.cshtml) - CSharp - } catch(Exception ex) {\n
+ HtmlContent - (465:29,0 [33] Blocks.cshtml)
+ IntermediateToken - (465:29,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (469:29,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (472:29,7 [26] Blocks.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (500:29,35 [10] Blocks.cshtml)
+ IntermediateToken - (500:29,35 [10] Blocks.cshtml) - CSharp - ex.Message
+ HtmlContent - (511:29,46 [6] Blocks.cshtml)
+ IntermediateToken - (511:29,46 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (515:29,50 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (517:30,0 [3] Blocks.cshtml)
+ IntermediateToken - (517:30,0 [3] Blocks.cshtml) - CSharp - }\n
+ HtmlContent - (520:31,0 [14] Blocks.cshtml)
+ IntermediateToken - (520:31,0 [2] Blocks.cshtml) - Html - \n
+ IntermediateToken - (522:32,0 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (525:32,3 [9] Blocks.cshtml) - Html - i is now
+ CSharpExpression - (535:32,13 [1] Blocks.cshtml)
+ IntermediateToken - (535:32,13 [1] Blocks.cshtml) - CSharp - i
+ HtmlContent - (536:32,14 [8] Blocks.cshtml)
+ IntermediateToken - (536:32,14 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (540:32,18 [4] Blocks.cshtml) - Html - \n\n
+ CSharpCode - (545:34,1 [22] Blocks.cshtml)
+ IntermediateToken - (545:34,1 [22] Blocks.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (567:35,0 [53] Blocks.cshtml)
+ IntermediateToken - (567:35,0 [4] Blocks.cshtml) - Html -
+ IntermediateToken - (571:35,4 [3] Blocks.cshtml) - Html - <p>
+ IntermediateToken - (574:35,7 [40] Blocks.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (614:35,47 [4] Blocks.cshtml) - Html - </p>
+ IntermediateToken - (618:35,51 [2] Blocks.cshtml) - Html - \n
+ CSharpCode - (620:36,0 [1] Blocks.cshtml)
+ IntermediateToken - (620:36,0 [1] Blocks.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml
new file mode 100644
index 0000000000..e2c134767e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml
@@ -0,0 +1,43 @@
+<body>
+ @{
+ var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()
+ {
+ ["John Doe"] = ("John", "Doe", true)
+ };
+
+ @* This is all C# 7 bits that should work. *@
+
+ int Sixteen = 0b0001_0000;
+ long BillionsAndBillions = 100_000_000_000;
+ double AvogadroConstant = 6.022_140_857_747_474e23;
+ decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+ }
+
+ @if (nameLookup.TryGetValue("John Doe", out var entry))
+ {
+ if (entry.Extra is bool alive)
+ {
+ // Do Something
+ }
+ }
+ <p>
+ Here's a very unique number: @(1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M)
+ </p>
+
+ <div>
+ @((First: "John", Last: "Doe").First) @* Value Tuples *@
+ </div>
+
+ @switch (entry.Extra)
+ {
+ case int age:
+ // Do something
+ break;
+ case IEnumerable<string> childrenNames:
+ // Do more something
+ break;
+ case null:
+ // Do even more of something
+ break;
+ }
+</body> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.codegen.cs
new file mode 100644
index 0000000000..84b5e22683
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.codegen.cs
@@ -0,0 +1,81 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+
+ var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()
+ {
+ ["John Doe"] = ("John", "Doe", true)
+ };
+
+
+
+#line default
+#line hidden
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+
+
+ int Sixteen = 0b0001_0000;
+ long BillionsAndBillions = 100_000_000_000;
+ double AvogadroConstant = 6.022_140_857_747_474e23;
+ decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+
+
+#line default
+#line hidden
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ if (nameLookup.TryGetValue("John Doe", out var entry))
+ {
+ if (entry.Extra is bool alive)
+ {
+ // Do Something
+ }
+ }
+
+#line default
+#line hidden
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ __o = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+
+#line default
+#line hidden
+#line 28 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ __o = (First: "John", Last: "Doe").First;
+
+#line default
+#line hidden
+#line 31 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ switch (entry.Extra)
+ {
+ case int age:
+ // Do something
+ break;
+ case IEnumerable<string> childrenNames:
+ // Do more something
+ break;
+ case null:
+ // Do even more of something
+ break;
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.ir.txt
new file mode 100644
index 0000000000..f9f5e43b98
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.ir.txt
@@ -0,0 +1,45 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [12] CSharp7.cshtml)
+ IntermediateToken - (0:0,0 [6] CSharp7.cshtml) - Html - <body>
+ IntermediateToken - (6:0,6 [6] CSharp7.cshtml) - Html - \n
+ CSharpCode - (14:1,6 [187] CSharp7.cshtml)
+ IntermediateToken - (14:1,6 [187] CSharp7.cshtml) - CSharp - \n var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()\n {\n ["John Doe"] = ("John", "Doe", true)\n };\n\n
+ CSharpCode - (246:7,53 [253] CSharp7.cshtml)
+ IntermediateToken - (246:7,53 [253] CSharp7.cshtml) - CSharp - \n\n int Sixteen = 0b0001_0000;\n long BillionsAndBillions = 100_000_000_000;\n double AvogadroConstant = 6.022_140_857_747_474e23;\n decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;\n
+ HtmlContent - (502:14,0 [6] CSharp7.cshtml)
+ IntermediateToken - (502:14,0 [6] CSharp7.cshtml) - Html - \n
+ CSharpCode - (509:15,5 [159] CSharp7.cshtml)
+ IntermediateToken - (509:15,5 [159] CSharp7.cshtml) - CSharp - if (nameLookup.TryGetValue("John Doe", out var entry))\n {\n if (entry.Extra is bool alive)\n {\n // Do Something\n }\n }
+ HtmlContent - (668:21,5 [48] CSharp7.cshtml)
+ IntermediateToken - (668:21,5 [6] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (674:22,4 [3] CSharp7.cshtml) - Html - <p>
+ IntermediateToken - (677:22,7 [39] CSharp7.cshtml) - Html - \n Here's a very unique number:
+ CSharpExpression - (718:23,39 [62] CSharp7.cshtml)
+ IntermediateToken - (718:23,39 [62] CSharp7.cshtml) - CSharp - 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M
+ HtmlContent - (781:23,102 [33] CSharp7.cshtml)
+ IntermediateToken - (781:23,102 [6] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (787:24,4 [4] CSharp7.cshtml) - Html - </p>
+ IntermediateToken - (791:24,8 [8] CSharp7.cshtml) - Html - \n\n
+ IntermediateToken - (799:26,4 [5] CSharp7.cshtml) - Html - <div>
+ IntermediateToken - (804:26,9 [10] CSharp7.cshtml) - Html - \n
+ CSharpExpression - (816:27,10 [34] CSharp7.cshtml)
+ IntermediateToken - (816:27,10 [34] CSharp7.cshtml) - CSharp - (First: "John", Last: "Doe").First
+ HtmlContent - (872:28,0 [18] CSharp7.cshtml)
+ IntermediateToken - (872:28,0 [4] CSharp7.cshtml) - Html -
+ IntermediateToken - (876:28,4 [6] CSharp7.cshtml) - Html - </div>
+ IntermediateToken - (882:28,10 [8] CSharp7.cshtml) - Html - \n\n
+ CSharpCode - (891:30,5 [291] CSharp7.cshtml)
+ IntermediateToken - (891:30,5 [291] CSharp7.cshtml) - CSharp - switch (entry.Extra)\n {\n case int age:\n // Do something\n break;\n case IEnumerable<string> childrenNames:\n // Do more something\n break;\n case null:\n // Do even more of something\n break;\n }
+ HtmlContent - (1182:41,5 [9] CSharp7.cshtml)
+ IntermediateToken - (1182:41,5 [2] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (1184:42,0 [7] CSharp7.cshtml) - Html - </body>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.mappings.txt
new file mode 100644
index 0000000000..821eec5170
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_DesignTime.mappings.txt
@@ -0,0 +1,88 @@
+Source Location: (14:1,6 [187] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|
+ var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()
+ {
+ ["John Doe"] = ("John", "Doe", true)
+ };
+
+ |
+Generated Location: (719:18,6 [187] )
+|
+ var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()
+ {
+ ["John Doe"] = ("John", "Doe", true)
+ };
+
+ |
+
+Source Location: (246:7,53 [253] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|
+
+ int Sixteen = 0b0001_0000;
+ long BillionsAndBillions = 100_000_000_000;
+ double AvogadroConstant = 6.022_140_857_747_474e23;
+ decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+ |
+Generated Location: (1075:29,53 [253] )
+|
+
+ int Sixteen = 0b0001_0000;
+ long BillionsAndBillions = 100_000_000_000;
+ double AvogadroConstant = 6.022_140_857_747_474e23;
+ decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+ |
+
+Source Location: (509:15,5 [159] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|if (nameLookup.TryGetValue("John Doe", out var entry))
+ {
+ if (entry.Extra is bool alive)
+ {
+ // Do Something
+ }
+ }|
+Generated Location: (1450:40,5 [159] )
+|if (nameLookup.TryGetValue("John Doe", out var entry))
+ {
+ if (entry.Extra is bool alive)
+ {
+ // Do Something
+ }
+ }|
+
+Source Location: (718:23,39 [62] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M|
+Generated Location: (1765:51,39 [62] )
+|1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M|
+
+Source Location: (816:27,10 [34] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|(First: "John", Last: "Doe").First|
+Generated Location: (1955:56,10 [34] )
+|(First: "John", Last: "Doe").First|
+
+Source Location: (891:30,5 [291] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml)
+|switch (entry.Extra)
+ {
+ case int age:
+ // Do something
+ break;
+ case IEnumerable<string> childrenNames:
+ // Do more something
+ break;
+ case null:
+ // Do even more of something
+ break;
+ }|
+Generated Location: (2112:61,5 [291] )
+|switch (entry.Extra)
+ {
+ case int age:
+ // Do something
+ break;
+ case IEnumerable<string> childrenNames:
+ // Do more something
+ break;
+ case null:
+ // Do even more of something
+ break;
+ }|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.codegen.cs
new file mode 100644
index 0000000000..535e7351ce
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.codegen.cs
@@ -0,0 +1,84 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "69466b91f73ea9f94ccef045495a0da11bb763c6"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"69466b91f73ea9f94ccef045495a0da11bb763c6", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<body>\r\n");
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+
+ var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()
+ {
+ ["John Doe"] = ("John", "Doe", true)
+ };
+
+
+
+#line default
+#line hidden
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+
+
+ int Sixteen = 0b0001_0000;
+ long BillionsAndBillions = 100_000_000_000;
+ double AvogadroConstant = 6.022_140_857_747_474e23;
+ decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
+
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ if (nameLookup.TryGetValue("John Doe", out var entry))
+ {
+ if (entry.Extra is bool alive)
+ {
+ // Do Something
+ }
+ }
+
+#line default
+#line hidden
+ WriteLiteral(" <p>\r\n Here\'s a very unique number: ");
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ Write(1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n </p>\r\n\r\n <div>\r\n ");
+#line 28 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ Write((First: "John", Last: "Doe").First);
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ WriteLiteral("\r\n </div>\r\n\r\n");
+#line 31 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7.cshtml"
+ switch (entry.Extra)
+ {
+ case int age:
+ // Do something
+ break;
+ case IEnumerable<string> childrenNames:
+ // Do more something
+ break;
+ case null:
+ // Do even more of something
+ break;
+ }
+
+#line default
+#line hidden
+ WriteLiteral("</body>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.ir.txt
new file mode 100644
index 0000000000..ff3f1b48ff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CSharp7_Runtime.ir.txt
@@ -0,0 +1,48 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CSharp7_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [8] CSharp7.cshtml)
+ IntermediateToken - (0:0,0 [6] CSharp7.cshtml) - Html - <body>
+ IntermediateToken - (6:0,6 [2] CSharp7.cshtml) - Html - \n
+ CSharpCode - (8:1,0 [4] CSharp7.cshtml)
+ IntermediateToken - (8:1,0 [4] CSharp7.cshtml) - CSharp -
+ CSharpCode - (14:1,6 [187] CSharp7.cshtml)
+ IntermediateToken - (14:1,6 [187] CSharp7.cshtml) - CSharp - \n var nameLookup = new Dictionary<string, (string FirstName, string LastName, object Extra)>()\n {\n ["John Doe"] = ("John", "Doe", true)\n };\n\n
+ CSharpCode - (246:7,53 [253] CSharp7.cshtml)
+ IntermediateToken - (246:7,53 [253] CSharp7.cshtml) - CSharp - \n\n int Sixteen = 0b0001_0000;\n long BillionsAndBillions = 100_000_000_000;\n double AvogadroConstant = 6.022_140_857_747_474e23;\n decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;\n
+ HtmlContent - (502:14,0 [2] CSharp7.cshtml)
+ IntermediateToken - (502:14,0 [2] CSharp7.cshtml) - Html - \n
+ CSharpCode - (504:15,0 [4] CSharp7.cshtml)
+ IntermediateToken - (504:15,0 [4] CSharp7.cshtml) - CSharp -
+ CSharpCode - (509:15,5 [161] CSharp7.cshtml)
+ IntermediateToken - (509:15,5 [161] CSharp7.cshtml) - CSharp - if (nameLookup.TryGetValue("John Doe", out var entry))\n {\n if (entry.Extra is bool alive)\n {\n // Do Something\n }\n }\n
+ HtmlContent - (670:22,0 [46] CSharp7.cshtml)
+ IntermediateToken - (670:22,0 [4] CSharp7.cshtml) - Html -
+ IntermediateToken - (674:22,4 [3] CSharp7.cshtml) - Html - <p>
+ IntermediateToken - (677:22,7 [39] CSharp7.cshtml) - Html - \n Here's a very unique number:
+ CSharpExpression - (718:23,39 [62] CSharp7.cshtml)
+ IntermediateToken - (718:23,39 [62] CSharp7.cshtml) - CSharp - 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M
+ HtmlContent - (781:23,102 [33] CSharp7.cshtml)
+ IntermediateToken - (781:23,102 [6] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (787:24,4 [4] CSharp7.cshtml) - Html - </p>
+ IntermediateToken - (791:24,8 [8] CSharp7.cshtml) - Html - \n\n
+ IntermediateToken - (799:26,4 [5] CSharp7.cshtml) - Html - <div>
+ IntermediateToken - (804:26,9 [2] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (806:27,0 [8] CSharp7.cshtml) - Html -
+ CSharpExpression - (816:27,10 [34] CSharp7.cshtml)
+ IntermediateToken - (816:27,10 [34] CSharp7.cshtml) - CSharp - (First: "John", Last: "Doe").First
+ HtmlContent - (851:27,45 [1] CSharp7.cshtml)
+ IntermediateToken - (851:27,45 [1] CSharp7.cshtml) - Html -
+ HtmlContent - (870:27,64 [16] CSharp7.cshtml)
+ IntermediateToken - (870:27,64 [6] CSharp7.cshtml) - Html - \n
+ IntermediateToken - (876:28,4 [6] CSharp7.cshtml) - Html - </div>
+ IntermediateToken - (882:28,10 [4] CSharp7.cshtml) - Html - \n\n
+ CSharpCode - (886:30,0 [4] CSharp7.cshtml)
+ IntermediateToken - (886:30,0 [4] CSharp7.cshtml) - CSharp -
+ CSharpCode - (891:30,5 [293] CSharp7.cshtml)
+ IntermediateToken - (891:30,5 [293] CSharp7.cshtml) - CSharp - switch (entry.Extra)\n {\n case int age:\n // Do something\n break;\n case IEnumerable<string> childrenNames:\n // Do more something\n break;\n case null:\n // Do even more of something\n break;\n }\n
+ HtmlContent - (1184:42,0 [7] CSharp7.cshtml)
+ IntermediateToken - (1184:42,0 [7] CSharp7.cshtml) - Html - </body>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml
new file mode 100644
index 0000000000..1c78883a10
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml
@@ -0,0 +1,5 @@
+@{
+ for(int i = 1; i <= 10; i++) {
+ Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml
new file mode 100644
index 0000000000..38417d481c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml
@@ -0,0 +1 @@
+@{ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.codegen.cs
new file mode 100644
index 0000000000..8160ceea8d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.codegen.cs
@@ -0,0 +1,23 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..c3072c6248
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml(1,2): Error RZ1006: The code block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.ir.txt
new file mode 100644
index 0000000000..764d204441
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.ir.txt
@@ -0,0 +1,13 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [0] CodeBlockAtEOF.cshtml)
+ IntermediateToken - (2:0,2 [0] CodeBlockAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.mappings.txt
new file mode 100644
index 0000000000..91017073c6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (2:0,2 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml)
+||
+Generated Location: (651:17,14 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.codegen.cs
new file mode 100644
index 0000000000..95ce16e337
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.codegen.cs
@@ -0,0 +1,18 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b4fbc3b07404cc5be74ae0ba920a16e9cf39a378"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"b4fbc3b07404cc5be74ae0ba920a16e9cf39a378", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..c3072c6248
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF.cshtml(1,2): Error RZ1006: The code block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.ir.txt
new file mode 100644
index 0000000000..daf2692204
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockAtEOF_Runtime.ir.txt
@@ -0,0 +1,8 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockAtEOF_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [0] CodeBlockAtEOF.cshtml)
+ IntermediateToken - (2:0,2 [0] CodeBlockAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml
new file mode 100644
index 0000000000..9c34a940eb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml
@@ -0,0 +1,4 @@
+@{
+ var a = 1; <text>foo</text>
+ var b = 1; <text>bar @(a+b)</text>
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.codegen.cs
new file mode 100644
index 0000000000..5df492cc3c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.codegen.cs
@@ -0,0 +1,41 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+
+ var a = 1;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+
+ var b = 1;
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+ __o = a+b;
+
+#line default
+#line hidden
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.ir.txt
new file mode 100644
index 0000000000..8a220afc95
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [17] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (2:0,2 [17] CodeBlockWithTextElement.cshtml) - CSharp - \n var a = 1;
+ HtmlContent - (25:1,21 [3] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (25:1,21 [3] CodeBlockWithTextElement.cshtml) - Html - foo
+ CSharpCode - (35:1,31 [22] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (35:1,31 [22] CodeBlockWithTextElement.cshtml) - CSharp - \n var b = 1;
+ HtmlContent - (63:2,23 [4] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (63:2,23 [4] CodeBlockWithTextElement.cshtml) - Html - bar
+ CSharpExpression - (69:2,29 [3] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (69:2,29 [3] CodeBlockWithTextElement.cshtml) - CSharp - a+b
+ CSharpCode - (80:2,40 [2] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (80:2,40 [2] CodeBlockWithTextElement.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.mappings.txt
new file mode 100644
index 0000000000..5279d46d18
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_DesignTime.mappings.txt
@@ -0,0 +1,26 @@
+Source Location: (2:0,2 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml)
+|
+ var a = 1; |
+Generated Location: (749:18,2 [17] )
+|
+ var a = 1; |
+
+Source Location: (35:1,31 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml)
+|
+ var b = 1; |
+Generated Location: (930:24,31 [22] )
+|
+ var b = 1; |
+
+Source Location: (69:2,29 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml)
+|a+b|
+Generated Location: (1123:30,38 [3] )
+|a+b|
+
+Source Location: (80:2,40 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml)
+|
+|
+Generated Location: (1221:34,61 [2] )
+|
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.codegen.cs
new file mode 100644
index 0000000000..0bd342205c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.codegen.cs
@@ -0,0 +1,37 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b794c71d64ba4731b2802f7d0dae1f863a9f9dd9"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"b794c71d64ba4731b2802f7d0dae1f863a9f9dd9", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+
+ var a = 1;
+
+#line default
+#line hidden
+ WriteLiteral("foo");
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+
+ var b = 1;
+
+#line default
+#line hidden
+ WriteLiteral("bar ");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement.cshtml"
+ Write(a+b);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.ir.txt
new file mode 100644
index 0000000000..0c163f3a41
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlockWithTextElement_Runtime.ir.txt
@@ -0,0 +1,18 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlockWithTextElement_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [17] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (2:0,2 [17] CodeBlockWithTextElement.cshtml) - CSharp - \n var a = 1;
+ HtmlContent - (25:1,21 [3] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (25:1,21 [3] CodeBlockWithTextElement.cshtml) - Html - foo
+ CSharpCode - (35:1,31 [22] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (35:1,31 [22] CodeBlockWithTextElement.cshtml) - CSharp - \n var b = 1;
+ HtmlContent - (63:2,23 [4] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (63:2,23 [4] CodeBlockWithTextElement.cshtml) - Html - bar
+ CSharpExpression - (69:2,29 [3] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (69:2,29 [3] CodeBlockWithTextElement.cshtml) - CSharp - a+b
+ CSharpCode - (80:2,40 [2] CodeBlockWithTextElement.cshtml)
+ IntermediateToken - (80:2,40 [2] CodeBlockWithTextElement.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ad75abc7df
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.codegen.cs
@@ -0,0 +1,30 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml"
+
+ for(int i = 1; i <= 10; i++) {
+ Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.ir.txt
new file mode 100644
index 0000000000..2dadb8d1fa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.ir.txt
@@ -0,0 +1,13 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [115] CodeBlock.cshtml)
+ IntermediateToken - (2:0,2 [115] CodeBlock.cshtml) - CSharp - \n for(int i = 1; i <= 10; i++) {\n Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.mappings.txt
new file mode 100644
index 0000000000..8d4bb56709
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_DesignTime.mappings.txt
@@ -0,0 +1,13 @@
+Source Location: (2:0,2 [115] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml)
+|
+ for(int i = 1; i <= 10; i++) {
+ Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");
+ }
+|
+Generated Location: (719:18,2 [115] )
+|
+ for(int i = 1; i <= 10; i++) {
+ Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.codegen.cs
new file mode 100644
index 0000000000..ccc2670366
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.codegen.cs
@@ -0,0 +1,26 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d570564dcb19afbfb9fcd1b8a7e339d22c0d0c97"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d570564dcb19afbfb9fcd1b8a7e339d22c0d0c97", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock.cshtml"
+
+ for(int i = 1; i <= 10; i++) {
+ Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.ir.txt
new file mode 100644
index 0000000000..f700c27032
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CodeBlock_Runtime.ir.txt
@@ -0,0 +1,8 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CodeBlock_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [115] CodeBlock.cshtml)
+ IntermediateToken - (2:0,2 [115] CodeBlock.cshtml) - CSharp - \n for(int i = 1; i <= 10; i++) {\n Output.Write("<p>Hello from C#, #" + i.ToString() + "</p>");\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml
new file mode 100644
index 0000000000..bc85b1d389
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml
@@ -0,0 +1,37 @@
+@addTagHelper "*, TestAssembly"
+
+@if (true)
+{
+ var checkbox = "checkbox";
+
+ <div class="randomNonTagHelperAttribute">
+ <p age="@@@(1+2)" class="@@string"></p>
+ <p time="Current Time: @DateTime.Now">
+ <h1>Set Time:</h1>
+ @if (false)
+ {
+ <p>New Time: <input type="text" value="" placeholder="Enter in a new time..."/></p>
+ }
+ else
+ {
+ <p>Current Time: <input type=@checkbox checked=true /></p>
+ <input tYPe='@(true ? "checkbox" : "anything")' />
+ <input type='@if(true) { <text>checkbox</text> } else { <text>anything</text> }'>
+ }
+ </p>
+ <p unbound="first value" age="@DateTimeOffset.Now.Year - 1970" unbound="second value" >
+ @{ var @object = false;}
+ <input ChecKED="@(@object)">
+ </p>
+ <p age="-1970 + @DateTimeOffset.Now.Year">
+ <input unbound="hello" unbound="world" checked="@(DateTimeOffset.Now.Year > 2014)" />
+ </p>
+ <p age="DateTimeOffset.Now.Year - 1970">
+ <input checked="DateTimeOffset.Now.Year > 2014">
+ </p>
+ <p age="@("My age is this long.".Length)">
+ <input checked=" @( DateTimeOffset.Now.Year ) > 2014 " />
+ </p>
+ @someMethod(@<p age="123" class="hello"><input checked=@checked /></p>)
+ </div>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..37b7b26436
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,207 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if (true)
+{
+ var checkbox = "checkbox";
+
+
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = @@(1+2);
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if (false)
+ {
+
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "text";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+
+ }
+ else
+ {
+
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __o = checkbox;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = string.Empty;
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+
+
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 18 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __o = true ? "checkbox" : "anything";
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = string.Empty;
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+
+
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if(true) {
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = string.Empty;
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+
+ }
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ var @object = false;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = (@object);
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __TestNamespace_PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = (DateTimeOffset.Now.Year > 2014);
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = -1970 + @DateTimeOffset.Now.Year;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = @( DateTimeOffset.Now.Year ) > 2014 ;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 32 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = ("My age is this long.".Length);
+
+#line default
+#line hidden
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __o = someMethod(item => new Template(async(__razor_template_writer) => {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = checked;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = 123;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..39903d2ef9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,298 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] ComplexTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] ComplexTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] ComplexTagHelpers.cshtml) - Html - \n\n
+ CSharpCode - (36:2,1 [52] ComplexTagHelpers.cshtml)
+ IntermediateToken - (36:2,1 [52] ComplexTagHelpers.cshtml) - CSharp - if (true)\n{\n var checkbox = "checkbox";\n\n
+ HtmlContent - (88:6,4 [51] ComplexTagHelpers.cshtml)
+ IntermediateToken - (88:6,4 [4] ComplexTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (92:6,8 [36] ComplexTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (128:6,44 [1] ComplexTagHelpers.cshtml) - Html - >
+ IntermediateToken - (129:6,45 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (139:7,8 [39] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (147:7,16 [8] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (147:7,16 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (149:7,18 [0] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (149:7,18 [6] ComplexTagHelpers.cshtml)
+ IntermediateToken - (149:7,18 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (150:7,19 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (151:7,20 [3] ComplexTagHelpers.cshtml) - CSharp - 1+2
+ IntermediateToken - (154:7,23 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (164:7,33 [1] ComplexTagHelpers.cshtml)
+ IntermediateToken - (164:7,33 [1] ComplexTagHelpers.cshtml) - Html - @
+ HtmlContent - (166:7,35 [6] ComplexTagHelpers.cshtml)
+ IntermediateToken - (166:7,35 [6] ComplexTagHelpers.cshtml) - Html - string
+ DefaultTagHelperExecute -
+ HtmlContent - (178:7,47 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (178:7,47 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (188:8,8 [531] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (226:8,46 [46] ComplexTagHelpers.cshtml)
+ IntermediateToken - (226:8,46 [14] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (240:9,12 [4] ComplexTagHelpers.cshtml) - Html - <h1>
+ IntermediateToken - (244:9,16 [9] ComplexTagHelpers.cshtml) - Html - Set Time:
+ IntermediateToken - (253:9,25 [5] ComplexTagHelpers.cshtml) - Html - </h1>
+ IntermediateToken - (258:9,30 [14] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (273:10,13 [43] ComplexTagHelpers.cshtml)
+ IntermediateToken - (273:10,13 [43] ComplexTagHelpers.cshtml) - CSharp - if (false)\n {\n
+ TagHelper - (316:12,16 [83] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (319:12,19 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (319:12,19 [10] ComplexTagHelpers.cshtml) - Html - New Time:
+ TagHelper - (329:12,29 [66] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (342:12,42 [4] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (342:12,42 [4] ComplexTagHelpers.cshtml)
+ IntermediateToken - (342:12,42 [4] ComplexTagHelpers.cshtml) - Html - text
+ DefaultTagHelperProperty - (342:12,42 [4] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (342:12,42 [4] ComplexTagHelpers.cshtml)
+ IntermediateToken - (342:12,42 [4] ComplexTagHelpers.cshtml) - Html - text
+ DefaultTagHelperHtmlAttribute - - value - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (355:12,55 [0] ComplexTagHelpers.cshtml)
+ IntermediateToken - (355:12,55 [0] ComplexTagHelpers.cshtml) - Html -
+ DefaultTagHelperHtmlAttribute - - placeholder - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (370:12,70 [22] ComplexTagHelpers.cshtml)
+ IntermediateToken - (370:12,70 [22] ComplexTagHelpers.cshtml) - Html - Enter in a new time...
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperExecute -
+ CSharpCode - (399:12,99 [66] ComplexTagHelpers.cshtml)
+ IntermediateToken - (399:12,99 [66] ComplexTagHelpers.cshtml) - CSharp - \n }\n else\n {\n
+ TagHelper - (465:16,16 [58] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (468:16,19 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (468:16,19 [14] ComplexTagHelpers.cshtml) - Html - Current Time:
+ TagHelper - (482:16,33 [37] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (494:16,45 [9] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (495:16,46 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (495:16,46 [8] ComplexTagHelpers.cshtml) - CSharp - checkbox
+ DefaultTagHelperProperty - (494:16,45 [9] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (495:16,46 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (495:16,46 [8] ComplexTagHelpers.cshtml) - CSharp - checkbox
+ DefaultTagHelperProperty - (512:16,63 [4] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (512:16,63 [4] ComplexTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperExecute -
+ CSharpCode - (523:16,74 [18] ComplexTagHelpers.cshtml)
+ IntermediateToken - (523:16,74 [18] ComplexTagHelpers.cshtml) - CSharp - \n
+ TagHelper - (541:17,16 [50] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (554:17,29 [33] ComplexTagHelpers.cshtml) - tYPe - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpExpression - (556:17,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (556:17,31 [30] ComplexTagHelpers.cshtml) - CSharp - true ? "checkbox" : "anything"
+ DefaultTagHelperProperty - (554:17,29 [33] ComplexTagHelpers.cshtml) - tYPe - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpExpression - (556:17,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (556:17,31 [30] ComplexTagHelpers.cshtml) - CSharp - true ? "checkbox" : "anything"
+ DefaultTagHelperExecute -
+ CSharpCode - (591:17,66 [18] ComplexTagHelpers.cshtml)
+ IntermediateToken - (591:17,66 [18] ComplexTagHelpers.cshtml) - CSharp - \n
+ TagHelper - (609:18,16 [81] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (622:18,29 [66] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpCode - (623:18,30 [11] ComplexTagHelpers.cshtml)
+ IntermediateToken - (623:18,30 [11] ComplexTagHelpers.cshtml) - CSharp - if(true) {
+ HtmlContent - (640:18,47 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (640:18,47 [8] ComplexTagHelpers.cshtml) - Html - checkbox
+ CSharpCode - (655:18,62 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (655:18,62 [10] ComplexTagHelpers.cshtml) - CSharp - } else {
+ HtmlContent - (671:18,78 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (671:18,78 [8] ComplexTagHelpers.cshtml) - Html - anything
+ CSharpCode - (686:18,93 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (686:18,93 [2] ComplexTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperProperty - (622:18,29 [66] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpCode - (623:18,30 [11] ComplexTagHelpers.cshtml)
+ IntermediateToken - (623:18,30 [11] ComplexTagHelpers.cshtml) - CSharp - if(true) {
+ HtmlContent - (640:18,47 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (640:18,47 [8] ComplexTagHelpers.cshtml) - Html - checkbox
+ CSharpCode - (655:18,62 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (655:18,62 [10] ComplexTagHelpers.cshtml) - CSharp - } else {
+ HtmlContent - (671:18,78 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (671:18,78 [8] ComplexTagHelpers.cshtml) - Html - anything
+ CSharpCode - (686:18,93 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (686:18,93 [2] ComplexTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperExecute -
+ CSharpCode - (690:18,97 [15] ComplexTagHelpers.cshtml)
+ IntermediateToken - (690:18,97 [15] ComplexTagHelpers.cshtml) - CSharp - \n }
+ HtmlContent - (705:19,13 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (705:19,13 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - time - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (197:8,17 [7] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (197:8,17 [7] ComplexTagHelpers.cshtml) - Html - Current
+ HtmlAttributeValue - (204:8,24 [6] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (205:8,25 [5] ComplexTagHelpers.cshtml) - Html - Time:
+ CSharpExpressionAttributeValue - (210:8,30 [14] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (212:8,32 [12] ComplexTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperExecute -
+ HtmlContent - (719:20,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (719:20,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (729:21,8 [181] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (816:21,95 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (816:21,95 [14] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (832:22,14 [21] ComplexTagHelpers.cshtml)
+ IntermediateToken - (832:22,14 [21] ComplexTagHelpers.cshtml) - CSharp - var @object = false;
+ HtmlContent - (856:23,0 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (856:23,0 [12] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (868:23,12 [28] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (884:23,28 [10] ComplexTagHelpers.cshtml) - ChecKED - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (885:23,29 [9] ComplexTagHelpers.cshtml)
+ IntermediateToken - (885:23,29 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (886:23,30 [7] ComplexTagHelpers.cshtml) - CSharp - @object
+ IntermediateToken - (893:23,37 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (896:23,40 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (896:23,40 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (741:21,20 [11] ComplexTagHelpers.cshtml)
+ IntermediateToken - (741:21,20 [11] ComplexTagHelpers.cshtml) - Html - first value
+ DefaultTagHelperProperty - (759:21,38 [31] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (760:21,39 [23] ComplexTagHelpers.cshtml)
+ IntermediateToken - (760:21,39 [23] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ IntermediateToken - (783:21,62 [2] ComplexTagHelpers.cshtml) - CSharp - -
+ IntermediateToken - (785:21,64 [5] ComplexTagHelpers.cshtml) - CSharp - 1970
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (801:21,80 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (801:21,80 [12] ComplexTagHelpers.cshtml) - Html - second value
+ DefaultTagHelperExecute -
+ HtmlContent - (910:24,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (910:24,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (920:25,8 [155] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (962:25,50 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (962:25,50 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (976:26,12 [85] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (992:26,28 [5] ComplexTagHelpers.cshtml)
+ IntermediateToken - (992:26,28 [5] ComplexTagHelpers.cshtml) - Html - hello
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (1008:26,44 [5] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1008:26,44 [5] ComplexTagHelpers.cshtml) - Html - world
+ DefaultTagHelperProperty - (1024:26,60 [33] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1025:26,61 [32] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1025:26,61 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1026:26,62 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year > 2014
+ IntermediateToken - (1056:26,92 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (1061:26,97 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1061:26,97 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (928:25,16 [32] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (928:25,16 [5] ComplexTagHelpers.cshtml) - CSharp - -1970
+ IntermediateToken - (933:25,21 [2] ComplexTagHelpers.cshtml) - CSharp - +
+ IntermediateToken - (935:25,23 [1] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (936:25,24 [24] ComplexTagHelpers.cshtml)
+ IntermediateToken - (936:25,24 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (937:25,25 [23] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ DefaultTagHelperExecute -
+ HtmlContent - (1075:27,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1075:27,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1085:28,8 [116] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (1125:28,48 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1125:28,48 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1139:29,12 [48] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1155:29,28 [30] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1155:29,28 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year > 2014
+ DefaultTagHelperExecute -
+ HtmlContent - (1187:29,60 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1187:29,60 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1093:28,16 [30] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1093:28,16 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year\-1970
+ DefaultTagHelperExecute -
+ HtmlContent - (1201:30,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1201:30,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1211:31,8 [133] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (1253:31,50 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1253:31,50 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1267:32,12 [63] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1283:32,28 [43] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1283:32,28 [3] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (1286:32,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1286:32,31 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (1287:32,32 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1288:32,33 [27] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ IntermediateToken - (1315:32,60 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ IntermediateToken - (1316:32,61 [2] ComplexTagHelpers.cshtml) - CSharp - >
+ IntermediateToken - (1318:32,63 [5] ComplexTagHelpers.cshtml) - CSharp - 2014
+ IntermediateToken - (1323:32,68 [3] ComplexTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperExecute -
+ HtmlContent - (1330:32,75 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1330:32,75 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1219:31,16 [32] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1220:31,17 [31] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1220:31,17 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1221:31,18 [29] ComplexTagHelpers.cshtml) - CSharp - "My age is this long.".Length
+ IntermediateToken - (1250:31,47 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (1344:33,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1344:33,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpExpression - (1355:34,9 [69] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1355:34,9 [11] ComplexTagHelpers.cshtml) - CSharp - someMethod(
+ Template - (1367:34,21 [57] ComplexTagHelpers.cshtml)
+ TagHelper - (1367:34,21 [57] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ TagHelper - (1394:34,48 [26] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1409:34,63 [8] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1410:34,64 [7] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1410:34,64 [7] ComplexTagHelpers.cshtml) - CSharp - checked
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1375:34,29 [3] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1375:34,29 [3] ComplexTagHelpers.cshtml) - CSharp - 123
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (1387:34,41 [5] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1387:34,41 [5] ComplexTagHelpers.cshtml) - Html - hello
+ DefaultTagHelperExecute -
+ IntermediateToken - (1424:34,78 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ HtmlContent - (1425:34,79 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1425:34,79 [6] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (1431:35,4 [6] ComplexTagHelpers.cshtml) - Html - </div>
+ CSharpCode - (1437:35,10 [3] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1437:35,10 [3] ComplexTagHelpers.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..35f9f98fe8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,293 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (675:13,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (36:2,1 [52] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|if (true)
+{
+ var checkbox = "checkbox";
+
+ |
+Generated Location: (1103:25,1 [52] )
+|if (true)
+{
+ var checkbox = "checkbox";
+
+ |
+
+Source Location: (147:7,16 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|@|
+Generated Location: (1409:35,33 [1] )
+|@|
+
+Source Location: (149:7,18 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+||
+Generated Location: (1410:35,34 [0] )
+||
+
+Source Location: (149:7,18 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|@|
+Generated Location: (1410:35,34 [1] )
+|@|
+
+Source Location: (150:7,19 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|(|
+Generated Location: (1411:35,35 [1] )
+|(|
+
+Source Location: (151:7,20 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|1+2|
+Generated Location: (1412:35,36 [3] )
+|1+2|
+
+Source Location: (154:7,23 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (1415:35,39 [1] )
+|)|
+
+Source Location: (273:10,13 [43] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|if (false)
+ {
+ |
+Generated Location: (1557:40,13 [43] )
+|if (false)
+ {
+ |
+
+Source Location: (399:12,99 [66] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|
+ }
+ else
+ {
+ |
+Generated Location: (2277:52,99 [66] )
+|
+ }
+ else
+ {
+ |
+
+Source Location: (495:16,46 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|checkbox|
+Generated Location: (2724:63,46 [8] )
+|checkbox|
+
+Source Location: (512:16,63 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|true|
+Generated Location: (3077:70,63 [4] )
+|true|
+
+Source Location: (523:16,74 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|
+ |
+Generated Location: (3296:75,86 [18] )
+|
+ |
+
+Source Location: (556:17,31 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|true ? "checkbox" : "anything"|
+Generated Location: (3649:80,31 [30] )
+|true ? "checkbox" : "anything"|
+
+Source Location: (591:17,66 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|
+ |
+Generated Location: (3945:86,78 [18] )
+|
+ |
+
+Source Location: (623:18,30 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|if(true) { |
+Generated Location: (4297:91,30 [11] )
+|if(true) { |
+
+Source Location: (655:18,62 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| } else { |
+Generated Location: (4497:96,62 [10] )
+| } else { |
+
+Source Location: (686:18,93 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| }|
+Generated Location: (4727:101,93 [2] )
+| }|
+
+Source Location: (690:18,97 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|
+ }|
+Generated Location: (5107:108,97 [15] )
+|
+ }|
+
+Source Location: (212:8,32 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (5375:115,32 [12] )
+|DateTime.Now|
+
+Source Location: (832:22,14 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| var @object = false;|
+Generated Location: (5529:120,14 [21] )
+| var @object = false;|
+
+Source Location: (885:23,29 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|(|
+Generated Location: (5927:127,42 [1] )
+|(|
+
+Source Location: (886:23,30 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|@object|
+Generated Location: (5928:127,43 [7] )
+|@object|
+
+Source Location: (893:23,37 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (5935:127,50 [1] )
+|)|
+
+Source Location: (760:21,39 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTimeOffset.Now.Year|
+Generated Location: (6197:133,38 [23] )
+|DateTimeOffset.Now.Year|
+
+Source Location: (783:21,62 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| -|
+Generated Location: (6220:133,61 [2] )
+| -|
+
+Source Location: (785:21,64 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| 1970|
+Generated Location: (6222:133,63 [5] )
+| 1970|
+
+Source Location: (1025:26,61 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|(|
+Generated Location: (6623:140,60 [1] )
+|(|
+
+Source Location: (1026:26,62 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTimeOffset.Now.Year > 2014|
+Generated Location: (6624:140,61 [30] )
+|DateTimeOffset.Now.Year > 2014|
+
+Source Location: (1056:26,92 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (6654:140,91 [1] )
+|)|
+
+Source Location: (928:25,16 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|-1970|
+Generated Location: (6911:146,33 [5] )
+|-1970|
+
+Source Location: (933:25,21 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| +|
+Generated Location: (6916:146,38 [2] )
+| +|
+
+Source Location: (935:25,23 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| |
+Generated Location: (6918:146,40 [1] )
+| |
+
+Source Location: (936:25,24 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|@|
+Generated Location: (6919:146,41 [1] )
+|@|
+
+Source Location: (937:25,25 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTimeOffset.Now.Year|
+Generated Location: (6920:146,42 [23] )
+|DateTimeOffset.Now.Year|
+
+Source Location: (1155:29,28 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTimeOffset.Now.Year > 2014|
+Generated Location: (7321:153,42 [30] )
+|DateTimeOffset.Now.Year > 2014|
+
+Source Location: (1093:28,16 [30] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|DateTimeOffset.Now.Year - 1970|
+Generated Location: (7607:159,33 [30] )
+|DateTimeOffset.Now.Year - 1970|
+
+Source Location: (1283:32,28 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| |
+Generated Location: (8015:166,42 [3] )
+| |
+
+Source Location: (1286:32,31 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|@|
+Generated Location: (8018:166,45 [1] )
+|@|
+
+Source Location: (1287:32,32 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|(|
+Generated Location: (8019:166,46 [1] )
+|(|
+
+Source Location: (1288:32,33 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| DateTimeOffset.Now.Year |
+Generated Location: (8020:166,47 [27] )
+| DateTimeOffset.Now.Year |
+
+Source Location: (1315:32,60 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (8047:166,74 [1] )
+|)|
+
+Source Location: (1316:32,61 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| >|
+Generated Location: (8048:166,75 [2] )
+| >|
+
+Source Location: (1318:32,63 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| 2014|
+Generated Location: (8050:166,77 [5] )
+| 2014|
+
+Source Location: (1323:32,68 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+| |
+Generated Location: (8055:166,82 [3] )
+| |
+
+Source Location: (1220:31,17 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|(|
+Generated Location: (8314:172,33 [1] )
+|(|
+
+Source Location: (1221:31,18 [29] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|"My age is this long.".Length|
+Generated Location: (8315:172,34 [29] )
+|"My age is this long.".Length|
+
+Source Location: (1250:31,47 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (8344:172,63 [1] )
+|)|
+
+Source Location: (1355:34,9 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|someMethod(|
+Generated Location: (8482:177,9 [11] )
+|someMethod(|
+
+Source Location: (1410:34,64 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|checked|
+Generated Location: (8900:181,63 [7] )
+|checked|
+
+Source Location: (1375:34,29 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|123|
+Generated Location: (9155:187,33 [3] )
+|123|
+
+Source Location: (1424:34,78 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|)|
+Generated Location: (9196:192,1 [1] )
+|)|
+
+Source Location: (1437:35,10 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml)
+|
+}|
+Generated Location: (9335:197,10 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..8602f83cc4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,493 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0ebc2a451a011b17f08d86ab395d2ef2bdaaf44e"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"0ebc2a451a011b17f08d86ab395d2ef2bdaaf44e", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", new global::Microsoft.AspNetCore.Html.HtmlString(""), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("placeholder", new global::Microsoft.AspNetCore.Html.HtmlString("Enter in a new time..."), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("first value"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("second value"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("world"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_7 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if (true)
+{
+ var checkbox = "checkbox";
+
+
+#line default
+#line hidden
+ WriteLiteral(" <div class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = @@(1+2);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("@");
+ WriteLiteral("string");
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("class", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n <h1>Set Time:</h1>\r\n");
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if (false)
+ {
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("New Time: ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ }
+ else
+ {
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Current Time: ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ WriteLiteral(checkbox);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Type = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("type", __TestNamespace_InputTagHelper.Type, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+#line 18 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ WriteLiteral(true ? "checkbox" : "anything");
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Type = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("tYPe", __TestNamespace_InputTagHelper.Type, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ if(true) {
+
+#line default
+#line hidden
+ WriteLiteral("checkbox");
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+ WriteLiteral("anything");
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Type = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("type", __TestNamespace_InputTagHelper.Type, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "time", 3, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 197, "Current", 197, 7, true);
+ AddHtmlAttributeValue(" ", 204, "Time:", 205, 6, true);
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 210, DateTime.Now, 211, 13, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n");
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ var @object = false;
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = (@object);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("ChecKED", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_4);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_6);
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = (DateTimeOffset.Now.Year > 2014);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = -1970 + @DateTimeOffset.Now.Year;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = DateTimeOffset.Now.Year > 2014;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = DateTimeOffset.Now.Year - 1970;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = @( DateTimeOffset.Now.Year ) > 2014 ;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 32 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = ("My age is this long.".Length);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+ Write(someMethod(item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = checked;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 35 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = 123;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_7);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n </div>\r\n");
+#line 37 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..92bc67f8c6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ComplexTagHelpers_Runtime.ir.txt
@@ -0,0 +1,299 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ComplexTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - value - - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - placeholder - Enter in a new time... - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - unbound - first value - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_4 - unbound - second value - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - unbound - hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_6 - unbound - world - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_7 - class - hello - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (36:2,1 [48] ComplexTagHelpers.cshtml)
+ IntermediateToken - (36:2,1 [48] ComplexTagHelpers.cshtml) - CSharp - if (true)\n{\n var checkbox = "checkbox";\n\n
+ HtmlContent - (84:6,0 [55] ComplexTagHelpers.cshtml)
+ IntermediateToken - (84:6,0 [4] ComplexTagHelpers.cshtml) - Html -
+ IntermediateToken - (88:6,4 [4] ComplexTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (92:6,8 [36] ComplexTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (128:6,44 [1] ComplexTagHelpers.cshtml) - Html - >
+ IntermediateToken - (129:6,45 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (139:7,8 [39] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (147:7,16 [8] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (147:7,16 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (149:7,18 [0] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (149:7,18 [6] ComplexTagHelpers.cshtml)
+ IntermediateToken - (149:7,18 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (150:7,19 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (151:7,20 [3] ComplexTagHelpers.cshtml) - CSharp - 1+2
+ IntermediateToken - (154:7,23 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (164:7,33 [1] ComplexTagHelpers.cshtml)
+ IntermediateToken - (164:7,33 [1] ComplexTagHelpers.cshtml) - Html - @
+ HtmlContent - (166:7,35 [6] ComplexTagHelpers.cshtml)
+ IntermediateToken - (166:7,35 [6] ComplexTagHelpers.cshtml) - Html - string
+ DefaultTagHelperExecute -
+ HtmlContent - (178:7,47 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (178:7,47 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (188:8,8 [531] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (226:8,46 [34] ComplexTagHelpers.cshtml)
+ IntermediateToken - (226:8,46 [14] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (240:9,12 [4] ComplexTagHelpers.cshtml) - Html - <h1>
+ IntermediateToken - (244:9,16 [9] ComplexTagHelpers.cshtml) - Html - Set Time:
+ IntermediateToken - (253:9,25 [5] ComplexTagHelpers.cshtml) - Html - </h1>
+ IntermediateToken - (258:9,30 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (260:10,0 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (260:10,0 [12] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpCode - (273:10,13 [27] ComplexTagHelpers.cshtml)
+ IntermediateToken - (273:10,13 [27] ComplexTagHelpers.cshtml) - CSharp - if (false)\n {\n
+ HtmlContent - (300:12,0 [16] ComplexTagHelpers.cshtml)
+ IntermediateToken - (300:12,0 [16] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (316:12,16 [83] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (319:12,19 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (319:12,19 [10] ComplexTagHelpers.cshtml) - Html - New Time:
+ TagHelper - (329:12,29 [66] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (342:12,42 [4] ComplexTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (342:12,42 [4] ComplexTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (399:12,99 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (399:12,99 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (401:13,0 [48] ComplexTagHelpers.cshtml)
+ IntermediateToken - (401:13,0 [48] ComplexTagHelpers.cshtml) - CSharp - }\n else\n {\n
+ HtmlContent - (449:16,0 [16] ComplexTagHelpers.cshtml)
+ IntermediateToken - (449:16,0 [16] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (465:16,16 [58] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (468:16,19 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (468:16,19 [14] ComplexTagHelpers.cshtml) - Html - Current Time:
+ TagHelper - (482:16,33 [37] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (494:16,45 [9] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (495:16,46 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (495:16,46 [8] ComplexTagHelpers.cshtml) - CSharp - checkbox
+ DefaultTagHelperProperty - (494:16,45 [9] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (495:16,46 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (495:16,46 [8] ComplexTagHelpers.cshtml) - CSharp - checkbox
+ DefaultTagHelperProperty - (512:16,63 [4] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (512:16,63 [4] ComplexTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (523:16,74 [18] ComplexTagHelpers.cshtml)
+ IntermediateToken - (523:16,74 [2] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (525:17,0 [16] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (541:17,16 [50] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (554:17,29 [33] ComplexTagHelpers.cshtml) - tYPe - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpExpression - (556:17,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (556:17,31 [30] ComplexTagHelpers.cshtml) - CSharp - true ? "checkbox" : "anything"
+ DefaultTagHelperProperty - (554:17,29 [33] ComplexTagHelpers.cshtml) - tYPe - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpExpression - (556:17,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (556:17,31 [30] ComplexTagHelpers.cshtml) - CSharp - true ? "checkbox" : "anything"
+ DefaultTagHelperExecute -
+ HtmlContent - (591:17,66 [18] ComplexTagHelpers.cshtml)
+ IntermediateToken - (591:17,66 [2] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (593:18,0 [16] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (609:18,16 [81] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (622:18,29 [66] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpCode - (623:18,30 [11] ComplexTagHelpers.cshtml)
+ IntermediateToken - (623:18,30 [11] ComplexTagHelpers.cshtml) - CSharp - if(true) {
+ HtmlContent - (640:18,47 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (640:18,47 [8] ComplexTagHelpers.cshtml) - Html - checkbox
+ CSharpCode - (655:18,62 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (655:18,62 [10] ComplexTagHelpers.cshtml) - CSharp - } else {
+ HtmlContent - (671:18,78 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (671:18,78 [8] ComplexTagHelpers.cshtml) - Html - anything
+ CSharpCode - (686:18,93 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (686:18,93 [2] ComplexTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperProperty - (622:18,29 [66] ComplexTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ CSharpCode - (623:18,30 [11] ComplexTagHelpers.cshtml)
+ IntermediateToken - (623:18,30 [11] ComplexTagHelpers.cshtml) - CSharp - if(true) {
+ HtmlContent - (640:18,47 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (640:18,47 [8] ComplexTagHelpers.cshtml) - Html - checkbox
+ CSharpCode - (655:18,62 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (655:18,62 [10] ComplexTagHelpers.cshtml) - CSharp - } else {
+ HtmlContent - (671:18,78 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (671:18,78 [8] ComplexTagHelpers.cshtml) - Html - anything
+ CSharpCode - (686:18,93 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (686:18,93 [2] ComplexTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperExecute -
+ HtmlContent - (690:18,97 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (690:18,97 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (692:19,0 [15] ComplexTagHelpers.cshtml)
+ IntermediateToken - (692:19,0 [15] ComplexTagHelpers.cshtml) - CSharp - }\n
+ HtmlContent - (707:20,0 [8] ComplexTagHelpers.cshtml)
+ IntermediateToken - (707:20,0 [8] ComplexTagHelpers.cshtml) - Html -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - time - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (197:8,17 [7] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (197:8,17 [7] ComplexTagHelpers.cshtml) - Html - Current
+ HtmlAttributeValue - (204:8,24 [6] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (205:8,25 [5] ComplexTagHelpers.cshtml) - Html - Time:
+ CSharpExpressionAttributeValue - (210:8,30 [14] ComplexTagHelpers.cshtml) -
+ IntermediateToken - (212:8,32 [12] ComplexTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperExecute -
+ HtmlContent - (719:20,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (719:20,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (729:21,8 [181] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (816:21,95 [2] ComplexTagHelpers.cshtml)
+ IntermediateToken - (816:21,95 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (818:22,0 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (818:22,0 [12] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpCode - (832:22,14 [21] ComplexTagHelpers.cshtml)
+ IntermediateToken - (832:22,14 [21] ComplexTagHelpers.cshtml) - CSharp - var @object = false;
+ HtmlContent - (856:23,0 [12] ComplexTagHelpers.cshtml)
+ IntermediateToken - (856:23,0 [12] ComplexTagHelpers.cshtml) - Html -
+ TagHelper - (868:23,12 [28] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (884:23,28 [10] ComplexTagHelpers.cshtml) - ChecKED - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (885:23,29 [9] ComplexTagHelpers.cshtml)
+ IntermediateToken - (885:23,29 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (886:23,30 [7] ComplexTagHelpers.cshtml) - CSharp - @object
+ IntermediateToken - (893:23,37 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (896:23,40 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (896:23,40 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ DefaultTagHelperProperty - (759:21,38 [31] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (760:21,39 [23] ComplexTagHelpers.cshtml)
+ IntermediateToken - (760:21,39 [23] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ IntermediateToken - (783:21,62 [2] ComplexTagHelpers.cshtml) - CSharp - -
+ IntermediateToken - (785:21,64 [5] ComplexTagHelpers.cshtml) - CSharp - 1970
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_4
+ DefaultTagHelperExecute -
+ HtmlContent - (910:24,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (910:24,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (920:25,8 [155] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (962:25,50 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (962:25,50 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (976:26,12 [85] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_6
+ DefaultTagHelperProperty - (1024:26,60 [33] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1025:26,61 [32] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1025:26,61 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1026:26,62 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year > 2014
+ IntermediateToken - (1056:26,92 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (1061:26,97 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1061:26,97 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (928:25,16 [32] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (928:25,16 [5] ComplexTagHelpers.cshtml) - CSharp - -1970
+ IntermediateToken - (933:25,21 [2] ComplexTagHelpers.cshtml) - CSharp - +
+ IntermediateToken - (935:25,23 [1] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (936:25,24 [24] ComplexTagHelpers.cshtml)
+ IntermediateToken - (936:25,24 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (937:25,25 [23] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ DefaultTagHelperExecute -
+ HtmlContent - (1075:27,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1075:27,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1085:28,8 [116] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (1125:28,48 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1125:28,48 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1139:29,12 [48] ComplexTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1155:29,28 [30] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1155:29,28 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year > 2014
+ DefaultTagHelperExecute -
+ HtmlContent - (1187:29,60 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1187:29,60 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1093:28,16 [30] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1093:28,16 [30] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year\-1970
+ DefaultTagHelperExecute -
+ HtmlContent - (1201:30,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1201:30,12 [10] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1211:31,8 [133] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (1253:31,50 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1253:31,50 [14] ComplexTagHelpers.cshtml) - Html - \n
+ TagHelper - (1267:32,12 [63] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1283:32,28 [43] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1283:32,28 [3] ComplexTagHelpers.cshtml) - CSharp -
+ CSharpExpression - (1286:32,31 [30] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1286:32,31 [1] ComplexTagHelpers.cshtml) - CSharp - @
+ IntermediateToken - (1287:32,32 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1288:32,33 [27] ComplexTagHelpers.cshtml) - CSharp - DateTimeOffset.Now.Year
+ IntermediateToken - (1315:32,60 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ IntermediateToken - (1316:32,61 [2] ComplexTagHelpers.cshtml) - CSharp - >
+ IntermediateToken - (1318:32,63 [5] ComplexTagHelpers.cshtml) - CSharp - 2014
+ IntermediateToken - (1323:32,68 [3] ComplexTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperExecute -
+ HtmlContent - (1330:32,75 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1330:32,75 [10] ComplexTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1219:31,16 [32] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1220:31,17 [31] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1220:31,17 [1] ComplexTagHelpers.cshtml) - CSharp - (
+ IntermediateToken - (1221:31,18 [29] ComplexTagHelpers.cshtml) - CSharp - "My age is this long.".Length
+ IntermediateToken - (1250:31,47 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (1344:33,12 [10] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1344:33,12 [2] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (1346:34,0 [8] ComplexTagHelpers.cshtml) - Html -
+ CSharpExpression - (1355:34,9 [69] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1355:34,9 [11] ComplexTagHelpers.cshtml) - CSharp - someMethod(
+ Template - (1367:34,21 [57] ComplexTagHelpers.cshtml)
+ TagHelper - (1367:34,21 [57] ComplexTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ TagHelper - (1394:34,48 [26] ComplexTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (1409:34,63 [8] ComplexTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (1410:34,64 [7] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1410:34,64 [7] ComplexTagHelpers.cshtml) - CSharp - checked
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (1375:34,29 [3] ComplexTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (1375:34,29 [3] ComplexTagHelpers.cshtml) - CSharp - 123
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_7
+ DefaultTagHelperExecute -
+ IntermediateToken - (1424:34,78 [1] ComplexTagHelpers.cshtml) - CSharp - )
+ HtmlContent - (1425:34,79 [14] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1425:34,79 [6] ComplexTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (1431:35,4 [6] ComplexTagHelpers.cshtml) - Html - </div>
+ IntermediateToken - (1437:35,10 [2] ComplexTagHelpers.cshtml) - Html - \n
+ CSharpCode - (1439:36,0 [1] ComplexTagHelpers.cshtml)
+ IntermediateToken - (1439:36,0 [1] ComplexTagHelpers.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml
new file mode 100644
index 0000000000..be1a9c2079
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml
@@ -0,0 +1,15 @@
+@{
+ var ch = true;
+ var cls = "bar";
+ <a href="Foo" />
+ <p class="@cls" />
+ <p class="foo @cls" />
+ <p class="@cls foo" />
+ <input type="checkbox" checked="@ch" />
+ <input type="checkbox" checked="foo @ch" />
+ <p class="@if(cls != null) { @cls }" />
+ <a href="~/Foo" />
+ <script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
+ <script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")" type="text/javascript"></script>
+ <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..d603d44201
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.codegen.cs
@@ -0,0 +1,102 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+
+ var ch = true;
+ var cls = "bar";
+
+
+#line default
+#line hidden
+
+
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = cls;
+
+#line default
+#line hidden
+
+
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = cls;
+
+#line default
+#line hidden
+
+
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = cls;
+
+#line default
+#line hidden
+
+
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = ch;
+
+#line default
+#line hidden
+
+
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = ch;
+
+#line default
+#line hidden
+
+
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ if(cls != null) {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = cls;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ }
+
+#line default
+#line hidden
+
+
+
+
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = Url.Content("~/Scripts/jquery-1.6.2.min.js");
+
+#line default
+#line hidden
+
+
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ __o = Url.Content("~/Scripts/modernizr-2.0.6-development-only.js");
+
+#line default
+#line hidden
+
+
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..29abe0b400
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.ir.txt
@@ -0,0 +1,120 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [48] ConditionalAttributes.cshtml)
+ IntermediateToken - (2:0,2 [48] ConditionalAttributes.cshtml) - CSharp - \n var ch = true;\n var cls = "bar";\n
+ HtmlContent - (50:3,4 [16] ConditionalAttributes.cshtml)
+ IntermediateToken - (50:3,4 [2] ConditionalAttributes.cshtml) - Html - <a
+ IntermediateToken - (52:3,6 [11] ConditionalAttributes.cshtml) - Html - href="Foo"
+ IntermediateToken - (63:3,17 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (66:3,20 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (66:3,20 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (72:4,4 [2] ConditionalAttributes.cshtml)
+ IntermediateToken - (72:4,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (74:4,6 [13] ConditionalAttributes.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (82:4,14 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (83:4,15 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlContent - (87:4,19 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (87:4,19 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (90:4,22 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (90:4,22 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (96:5,4 [2] ConditionalAttributes.cshtml)
+ IntermediateToken - (96:5,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (98:5,6 [17] ConditionalAttributes.cshtml) - class=" - "
+ HtmlAttributeValue - (106:5,14 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (106:5,14 [3] ConditionalAttributes.cshtml) - Html - foo
+ CSharpExpressionAttributeValue - (109:5,17 [5] ConditionalAttributes.cshtml) -
+ IntermediateToken - (111:5,19 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlContent - (115:5,23 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (115:5,23 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (118:5,26 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (118:5,26 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (124:6,4 [2] ConditionalAttributes.cshtml)
+ IntermediateToken - (124:6,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (126:6,6 [17] ConditionalAttributes.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (134:6,14 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (135:6,15 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlAttributeValue - (138:6,18 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (139:6,19 [3] ConditionalAttributes.cshtml) - Html - foo
+ HtmlContent - (143:6,23 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (143:6,23 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (146:6,26 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (146:6,26 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (152:7,4 [22] ConditionalAttributes.cshtml)
+ IntermediateToken - (152:7,4 [6] ConditionalAttributes.cshtml) - Html - <input
+ IntermediateToken - (158:7,10 [16] ConditionalAttributes.cshtml) - Html - type="checkbox"
+ HtmlAttribute - (174:7,26 [14] ConditionalAttributes.cshtml) - checked=" - "
+ CSharpExpressionAttributeValue - (184:7,36 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (185:7,37 [2] ConditionalAttributes.cshtml) - CSharp - ch
+ HtmlContent - (188:7,40 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (188:7,40 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (191:7,43 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (191:7,43 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (197:8,4 [22] ConditionalAttributes.cshtml)
+ IntermediateToken - (197:8,4 [6] ConditionalAttributes.cshtml) - Html - <input
+ IntermediateToken - (203:8,10 [16] ConditionalAttributes.cshtml) - Html - type="checkbox"
+ HtmlAttribute - (219:8,26 [18] ConditionalAttributes.cshtml) - checked=" - "
+ HtmlAttributeValue - (229:8,36 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (229:8,36 [3] ConditionalAttributes.cshtml) - Html - foo
+ CSharpExpressionAttributeValue - (232:8,39 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (234:8,41 [2] ConditionalAttributes.cshtml) - CSharp - ch
+ HtmlContent - (237:8,44 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (237:8,44 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (240:8,47 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (240:8,47 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (246:9,4 [2] ConditionalAttributes.cshtml)
+ IntermediateToken - (246:9,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (248:9,6 [34] ConditionalAttributes.cshtml) - class=" - "
+ CSharpCodeAttributeValue - (256:9,14 [25] ConditionalAttributes.cshtml) -
+ IntermediateToken - (257:9,15 [18] ConditionalAttributes.cshtml) - CSharp - if(cls != null) {
+ CSharpExpression - (276:9,34 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (276:9,34 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ IntermediateToken - (279:9,37 [2] ConditionalAttributes.cshtml) - CSharp - }
+ HtmlContent - (282:9,40 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (282:9,40 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (285:9,43 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (285:9,43 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (291:10,4 [18] ConditionalAttributes.cshtml)
+ IntermediateToken - (291:10,4 [2] ConditionalAttributes.cshtml) - Html - <a
+ IntermediateToken - (293:10,6 [13] ConditionalAttributes.cshtml) - Html - href="~/Foo"
+ IntermediateToken - (306:10,19 [3] ConditionalAttributes.cshtml) - Html - />
+ CSharpCode - (309:10,22 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (309:10,22 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (315:11,4 [7] ConditionalAttributes.cshtml)
+ IntermediateToken - (315:11,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ HtmlAttribute - (322:11,11 [52] ConditionalAttributes.cshtml) - src=" - "
+ CSharpExpressionAttributeValue - (328:11,17 [45] ConditionalAttributes.cshtml) -
+ IntermediateToken - (329:11,18 [44] ConditionalAttributes.cshtml) - CSharp - Url.Content("~/Scripts/jquery-1.6.2.min.js")
+ HtmlContent - (374:11,63 [33] ConditionalAttributes.cshtml)
+ IntermediateToken - (374:11,63 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (397:11,86 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (398:11,87 [9] ConditionalAttributes.cshtml) - Html - </script>
+ CSharpCode - (407:11,96 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (407:11,96 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (413:12,4 [7] ConditionalAttributes.cshtml)
+ IntermediateToken - (413:12,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ HtmlAttribute - (420:12,11 [68] ConditionalAttributes.cshtml) - src=" - "
+ CSharpExpressionAttributeValue - (426:12,17 [61] ConditionalAttributes.cshtml) -
+ IntermediateToken - (427:12,18 [60] ConditionalAttributes.cshtml) - CSharp - Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")
+ HtmlContent - (488:12,79 [33] ConditionalAttributes.cshtml)
+ IntermediateToken - (488:12,79 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (511:12,102 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (512:12,103 [9] ConditionalAttributes.cshtml) - Html - </script>
+ CSharpCode - (521:12,112 [6] ConditionalAttributes.cshtml)
+ IntermediateToken - (521:12,112 [6] ConditionalAttributes.cshtml) - CSharp - \n
+ HtmlContent - (527:13,4 [111] ConditionalAttributes.cshtml)
+ IntermediateToken - (527:13,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ IntermediateToken - (534:13,11 [71] ConditionalAttributes.cshtml) - Html - src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"
+ IntermediateToken - (605:13,82 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (628:13,105 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (629:13,106 [9] ConditionalAttributes.cshtml) - Html - </script>
+ CSharpCode - (638:13,115 [2] ConditionalAttributes.cshtml)
+ IntermediateToken - (638:13,115 [2] ConditionalAttributes.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..6824785c85
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_DesignTime.mappings.txt
@@ -0,0 +1,138 @@
+Source Location: (2:0,2 [48] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ var ch = true;
+ var cls = "bar";
+ |
+Generated Location: (743:18,2 [48] )
+|
+ var ch = true;
+ var cls = "bar";
+ |
+
+Source Location: (66:3,20 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (856:25,32 [6] )
+|
+ |
+
+Source Location: (83:4,15 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|cls|
+Generated Location: (976:28,15 [3] )
+|cls|
+
+Source Location: (90:4,22 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (1047:32,34 [6] )
+|
+ |
+
+Source Location: (111:5,19 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|cls|
+Generated Location: (1171:35,19 [3] )
+|cls|
+
+Source Location: (118:5,26 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (1246:39,38 [6] )
+|
+ |
+
+Source Location: (135:6,15 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|cls|
+Generated Location: (1366:42,15 [3] )
+|cls|
+
+Source Location: (146:6,26 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (1441:46,38 [6] )
+|
+ |
+
+Source Location: (185:7,37 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|ch|
+Generated Location: (1583:49,37 [2] )
+|ch|
+
+Source Location: (191:7,43 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (1674:53,55 [6] )
+|
+ |
+
+Source Location: (234:8,41 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|ch|
+Generated Location: (1820:56,41 [2] )
+|ch|
+
+Source Location: (240:8,47 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (1915:60,59 [6] )
+|
+ |
+
+Source Location: (257:9,15 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|if(cls != null) { |
+Generated Location: (2036:63,15 [18] )
+|if(cls != null) { |
+
+Source Location: (276:9,34 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|cls|
+Generated Location: (2219:68,34 [3] )
+|cls|
+
+Source Location: (279:9,37 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+| }|
+Generated Location: (2391:73,37 [2] )
+| }|
+
+Source Location: (285:9,43 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (2481:77,55 [6] )
+|
+ |
+
+Source Location: (309:10,22 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (2523:79,34 [6] )
+|
+ |
+
+Source Location: (329:11,18 [44] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|Url.Content("~/Scripts/jquery-1.6.2.min.js")|
+Generated Location: (2647:82,18 [44] )
+|Url.Content("~/Scripts/jquery-1.6.2.min.js")|
+
+Source Location: (407:11,96 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (2833:86,108 [6] )
+|
+ |
+
+Source Location: (427:12,18 [60] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")|
+Generated Location: (2957:89,18 [60] )
+|Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")|
+
+Source Location: (521:12,112 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+ |
+Generated Location: (3175:93,124 [6] )
+|
+ |
+
+Source Location: (638:13,115 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml)
+|
+|
+Generated Location: (3310:95,127 [2] )
+|
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..d7a93987f6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.codegen.cs
@@ -0,0 +1,108 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f0a97e23ecfbaaaa77b528650156cb123ebdbe60"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f0a97e23ecfbaaaa77b528650156cb123ebdbe60", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+
+ var ch = true;
+ var cls = "bar";
+
+#line default
+#line hidden
+ WriteLiteral(" <a href=\"Foo\" />\r\n <p");
+ BeginWriteAttribute("class", " class=\"", 74, "\"", 86, 1);
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue("", 82, cls, 82, 4, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <p");
+ BeginWriteAttribute("class", " class=\"", 98, "\"", 114, 2);
+ WriteAttributeValue("", 106, "foo", 106, 3, true);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue(" ", 109, cls, 110, 4, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <p");
+ BeginWriteAttribute("class", " class=\"", 126, "\"", 142, 2);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue("", 134, cls, 134, 4, false);
+
+#line default
+#line hidden
+ WriteAttributeValue(" ", 138, "foo", 139, 4, true);
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <input type=\"checkbox\"");
+ BeginWriteAttribute("checked", " checked=\"", 174, "\"", 187, 1);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue("", 184, ch, 184, 3, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <input type=\"checkbox\"");
+ BeginWriteAttribute("checked", " checked=\"", 219, "\"", 236, 2);
+ WriteAttributeValue("", 229, "foo", 229, 3, true);
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue(" ", 232, ch, 233, 3, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <p");
+ BeginWriteAttribute("class", " class=\"", 248, "\"", 281, 1);
+ WriteAttributeValue("", 256, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ if(cls != null) {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ Write(cls);
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+ }
+
+#line default
+#line hidden
+ PopWriter();
+ }
+ ), 256, 25, false);
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n <a href=\"~/Foo\" />\r\n <script");
+ BeginWriteAttribute("src", " src=\"", 322, "\"", 373, 1);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue("", 328, Url.Content("~/Scripts/jquery-1.6.2.min.js"), 328, 45, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" type=\"text/javascript\"></script>\r\n <script");
+ BeginWriteAttribute("src", " src=\"", 420, "\"", 487, 1);
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes.cshtml"
+WriteAttributeValue("", 426, Url.Content("~/Scripts/modernizr-2.0.6-development-only.js"), 426, 61, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(" type=\"text/javascript\"></script>\r\n <script src=\"http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js\" type=\"text/javascript\"></script>\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..3b1e6f21df
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ConditionalAttributes_Runtime.ir.txt
@@ -0,0 +1,107 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ConditionalAttributes_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [44] ConditionalAttributes.cshtml)
+ IntermediateToken - (2:0,2 [44] ConditionalAttributes.cshtml) - CSharp - \n var ch = true;\n var cls = "bar";\n
+ HtmlContent - (46:3,0 [28] ConditionalAttributes.cshtml)
+ IntermediateToken - (46:3,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (50:3,4 [2] ConditionalAttributes.cshtml) - Html - <a
+ IntermediateToken - (52:3,6 [11] ConditionalAttributes.cshtml) - Html - href="Foo"
+ IntermediateToken - (63:3,17 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (66:3,20 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (68:4,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (72:4,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (74:4,6 [13] ConditionalAttributes.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (82:4,14 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (83:4,15 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlContent - (87:4,19 [11] ConditionalAttributes.cshtml)
+ IntermediateToken - (87:4,19 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (90:4,22 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (92:5,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (96:5,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (98:5,6 [17] ConditionalAttributes.cshtml) - class=" - "
+ HtmlAttributeValue - (106:5,14 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (106:5,14 [3] ConditionalAttributes.cshtml) - Html - foo
+ CSharpExpressionAttributeValue - (109:5,17 [5] ConditionalAttributes.cshtml) -
+ IntermediateToken - (111:5,19 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlContent - (115:5,23 [11] ConditionalAttributes.cshtml)
+ IntermediateToken - (115:5,23 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (118:5,26 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (120:6,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (124:6,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (126:6,6 [17] ConditionalAttributes.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (134:6,14 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (135:6,15 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ HtmlAttributeValue - (138:6,18 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (139:6,19 [3] ConditionalAttributes.cshtml) - Html - foo
+ HtmlContent - (143:6,23 [31] ConditionalAttributes.cshtml)
+ IntermediateToken - (143:6,23 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (146:6,26 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (148:7,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (152:7,4 [6] ConditionalAttributes.cshtml) - Html - <input
+ IntermediateToken - (158:7,10 [16] ConditionalAttributes.cshtml) - Html - type="checkbox"
+ HtmlAttribute - (174:7,26 [14] ConditionalAttributes.cshtml) - checked=" - "
+ CSharpExpressionAttributeValue - (184:7,36 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (185:7,37 [2] ConditionalAttributes.cshtml) - CSharp - ch
+ HtmlContent - (188:7,40 [31] ConditionalAttributes.cshtml)
+ IntermediateToken - (188:7,40 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (191:7,43 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (193:8,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (197:8,4 [6] ConditionalAttributes.cshtml) - Html - <input
+ IntermediateToken - (203:8,10 [16] ConditionalAttributes.cshtml) - Html - type="checkbox"
+ HtmlAttribute - (219:8,26 [18] ConditionalAttributes.cshtml) - checked=" - "
+ HtmlAttributeValue - (229:8,36 [3] ConditionalAttributes.cshtml) -
+ IntermediateToken - (229:8,36 [3] ConditionalAttributes.cshtml) - Html - foo
+ CSharpExpressionAttributeValue - (232:8,39 [4] ConditionalAttributes.cshtml) -
+ IntermediateToken - (234:8,41 [2] ConditionalAttributes.cshtml) - CSharp - ch
+ HtmlContent - (237:8,44 [11] ConditionalAttributes.cshtml)
+ IntermediateToken - (237:8,44 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (240:8,47 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (242:9,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (246:9,4 [2] ConditionalAttributes.cshtml) - Html - <p
+ HtmlAttribute - (248:9,6 [34] ConditionalAttributes.cshtml) - class=" - "
+ CSharpCodeAttributeValue - (256:9,14 [25] ConditionalAttributes.cshtml) -
+ IntermediateToken - (257:9,15 [18] ConditionalAttributes.cshtml) - CSharp - if(cls != null) {
+ CSharpExpression - (276:9,34 [3] ConditionalAttributes.cshtml)
+ IntermediateToken - (276:9,34 [3] ConditionalAttributes.cshtml) - CSharp - cls
+ IntermediateToken - (279:9,37 [2] ConditionalAttributes.cshtml) - CSharp - }
+ HtmlContent - (282:9,40 [40] ConditionalAttributes.cshtml)
+ IntermediateToken - (282:9,40 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (285:9,43 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (287:10,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (291:10,4 [2] ConditionalAttributes.cshtml) - Html - <a
+ IntermediateToken - (293:10,6 [13] ConditionalAttributes.cshtml) - Html - href="~/Foo"
+ IntermediateToken - (306:10,19 [3] ConditionalAttributes.cshtml) - Html - />
+ IntermediateToken - (309:10,22 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (311:11,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (315:11,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ HtmlAttribute - (322:11,11 [52] ConditionalAttributes.cshtml) - src=" - "
+ CSharpExpressionAttributeValue - (328:11,17 [45] ConditionalAttributes.cshtml) -
+ IntermediateToken - (329:11,18 [44] ConditionalAttributes.cshtml) - CSharp - Url.Content("~/Scripts/jquery-1.6.2.min.js")
+ HtmlContent - (374:11,63 [46] ConditionalAttributes.cshtml)
+ IntermediateToken - (374:11,63 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (397:11,86 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (398:11,87 [9] ConditionalAttributes.cshtml) - Html - </script>
+ IntermediateToken - (407:11,96 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (409:12,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (413:12,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ HtmlAttribute - (420:12,11 [68] ConditionalAttributes.cshtml) - src=" - "
+ CSharpExpressionAttributeValue - (426:12,17 [61] ConditionalAttributes.cshtml) -
+ IntermediateToken - (427:12,18 [60] ConditionalAttributes.cshtml) - CSharp - Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")
+ HtmlContent - (488:12,79 [152] ConditionalAttributes.cshtml)
+ IntermediateToken - (488:12,79 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (511:12,102 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (512:12,103 [9] ConditionalAttributes.cshtml) - Html - </script>
+ IntermediateToken - (521:12,112 [2] ConditionalAttributes.cshtml) - Html - \n
+ IntermediateToken - (523:13,0 [4] ConditionalAttributes.cshtml) - Html -
+ IntermediateToken - (527:13,4 [7] ConditionalAttributes.cshtml) - Html - <script
+ IntermediateToken - (534:13,11 [71] ConditionalAttributes.cshtml) - Html - src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"
+ IntermediateToken - (605:13,82 [23] ConditionalAttributes.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (628:13,105 [1] ConditionalAttributes.cshtml) - Html - >
+ IntermediateToken - (629:13,106 [9] ConditionalAttributes.cshtml) - Html - </script>
+ IntermediateToken - (638:13,115 [2] ConditionalAttributes.cshtml) - Html - \n
+ CSharpCode - (640:14,0 [0] ConditionalAttributes.cshtml)
+ IntermediateToken - (640:14,0 [0] ConditionalAttributes.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml
new file mode 100644
index 0000000000..c71c637b14
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml
@@ -0,0 +1,13 @@
+@addTagHelper "*, TestAssembly"
+
+<a href="~/">2 TagHelpers.</a>
+<a href=~/hello>1 TagHelper.</a>
+<a href="~/?hello=world">2 TagHelpers</a>
+<a href="~/@false?hello=world">2 TagHelpers</a>
+<a href=' ~/'>0 TagHelpers.</a>
+<a href=~/@false>1 TagHelper</a>
+<a href="~/?hello=world@false">1 TagHelper</a>
+<a href='~/?hello=world @false'>1 TagHelper</a>
+<input type="text" value="3 TagHelpers" />
+<input type='texty' value="3 TagHelpers" />
+<input type="checkbox" value="2 TagHelper" /> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..4eca82aaa6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.codegen.cs
@@ -0,0 +1,242 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "385650281a1d9679c38ffc205756c3c26f6927e7"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CssSelectorTagHelperAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"385650281a1d9679c38ffc205756c3c26f6927e7", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CssSelectorTagHelperAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", new global::Microsoft.AspNetCore.Html.HtmlString("~/"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", new global::Microsoft.AspNetCore.Html.HtmlString("~/hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", new global::Microsoft.AspNetCore.Html.HtmlString("~/?hello=world"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", new global::Microsoft.AspNetCore.Html.HtmlString("~/?hello=world@false"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", new global::Microsoft.AspNetCore.Html.HtmlString("3 TagHelpers"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "texty", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_7 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_8 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", new global::Microsoft.AspNetCore.Html.HtmlString("2 TagHelper"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.ATagHelper __TestNamespace_ATagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ private global::TestNamespace.ATagHelperMultipleSelectors __TestNamespace_ATagHelperMultipleSelectors;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ private global::TestNamespace.CatchAllTagHelper2 __TestNamespace_CatchAllTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("2 TagHelpers.");
+ }
+ );
+ __TestNamespace_ATagHelper = CreateTagHelper<global::TestNamespace.ATagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_ATagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("1 TagHelper.");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("2 TagHelpers");
+ }
+ );
+ __TestNamespace_ATagHelperMultipleSelectors = CreateTagHelper<global::TestNamespace.ATagHelperMultipleSelectors>();
+ __tagHelperExecutionContext.Add(__TestNamespace_ATagHelperMultipleSelectors);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("2 TagHelpers");
+ }
+ );
+ __TestNamespace_ATagHelperMultipleSelectors = CreateTagHelper<global::TestNamespace.ATagHelperMultipleSelectors>();
+ __tagHelperExecutionContext.Add(__TestNamespace_ATagHelperMultipleSelectors);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "href", 3, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 153, "~/", 153, 2, true);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml"
+AddHtmlAttributeValue("", 155, false, 155, 6, false);
+
+#line default
+#line hidden
+ AddHtmlAttributeValue("", 161, "?hello=world", 161, 12, true);
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n<a href=\' ~/\'>0 TagHelpers.</a>\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("1 TagHelper");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "href", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 234, "~/", 234, 2, true);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml"
+AddHtmlAttributeValue("", 236, false, 236, 6, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("1 TagHelper");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("1 TagHelper");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "href", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ AddHtmlAttributeValue("", 317, "~/?hello=world", 317, 14, true);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes.cshtml"
+AddHtmlAttributeValue(" ", 331, false, 332, 6, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_CatchAllTagHelper2 = CreateTagHelper<global::TestNamespace.CatchAllTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_CatchAllTagHelper2 = CreateTagHelper<global::TestNamespace.CatchAllTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper2);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_6.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_CatchAllTagHelper2 = CreateTagHelper<global::TestNamespace.CatchAllTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper2);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_7.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_7);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_8);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..ef34c24d71
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/CssSelectorTagHelperAttributes_Runtime.ir.txt
@@ -0,0 +1,137 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_CssSelectorTagHelperAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - href - ~/ - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - href - ~/hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - href - ~/?hello=world - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - href - ~/?hello=world@false - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_4 - type - text - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - value - 3 TagHelpers - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_6 - type - texty - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_7 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_8 - value - 2 TagHelper - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.ATagHelper - __TestNamespace_ATagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ FieldDeclaration - - private - global::TestNamespace.ATagHelperMultipleSelectors - __TestNamespace_ATagHelperMultipleSelectors
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper2 - __TestNamespace_CatchAllTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (33:1,0 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (35:2,0 [30] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (48:2,13 [13] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (48:2,13 [13] CssSelectorTagHelperAttributes.cshtml) - Html - 2 TagHelpers.
+ DefaultTagHelperCreate - - TestNamespace.ATagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (65:2,30 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (65:2,30 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (67:3,0 [32] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (83:3,16 [12] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (83:3,16 [12] CssSelectorTagHelperAttributes.cshtml) - Html - 1 TagHelper.
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (99:3,32 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (99:3,32 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (101:4,0 [41] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (126:4,25 [12] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (126:4,25 [12] CssSelectorTagHelperAttributes.cshtml) - Html - 2 TagHelpers
+ DefaultTagHelperCreate - - TestNamespace.ATagHelperMultipleSelectors
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ HtmlContent - (142:4,41 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (142:4,41 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (144:5,0 [47] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (175:5,31 [12] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (175:5,31 [12] CssSelectorTagHelperAttributes.cshtml) - Html - 2 TagHelpers
+ DefaultTagHelperCreate - - TestNamespace.ATagHelperMultipleSelectors
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - href - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (153:5,9 [2] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (153:5,9 [2] CssSelectorTagHelperAttributes.cshtml) - Html - ~/
+ CSharpExpressionAttributeValue - (155:5,11 [6] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (156:5,12 [5] CssSelectorTagHelperAttributes.cshtml) - CSharp - false
+ HtmlAttributeValue - (161:5,17 [12] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (161:5,17 [12] CssSelectorTagHelperAttributes.cshtml) - Html - ?hello=world
+ DefaultTagHelperExecute -
+ HtmlContent - (191:5,47 [35] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (191:5,47 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ IntermediateToken - (193:6,0 [2] CssSelectorTagHelperAttributes.cshtml) - Html - <a
+ IntermediateToken - (195:6,2 [11] CssSelectorTagHelperAttributes.cshtml) - Html - href=' ~/'
+ IntermediateToken - (206:6,13 [1] CssSelectorTagHelperAttributes.cshtml) - Html - >
+ IntermediateToken - (207:6,14 [13] CssSelectorTagHelperAttributes.cshtml) - Html - 0 TagHelpers.
+ IntermediateToken - (220:6,27 [4] CssSelectorTagHelperAttributes.cshtml) - Html - </a>
+ IntermediateToken - (224:6,31 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (226:7,0 [32] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (243:7,17 [11] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (243:7,17 [11] CssSelectorTagHelperAttributes.cshtml) - Html - 1 TagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - href - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (234:7,8 [2] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (234:7,8 [2] CssSelectorTagHelperAttributes.cshtml) - Html - ~/
+ CSharpExpressionAttributeValue - (236:7,10 [6] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (237:7,11 [5] CssSelectorTagHelperAttributes.cshtml) - CSharp - false
+ DefaultTagHelperExecute -
+ HtmlContent - (258:7,32 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (258:7,32 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (260:8,0 [46] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (291:8,31 [11] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (291:8,31 [11] CssSelectorTagHelperAttributes.cshtml) - Html - 1 TagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ DefaultTagHelperExecute -
+ HtmlContent - (306:8,46 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (306:8,46 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (308:9,0 [47] CssSelectorTagHelperAttributes.cshtml) - a - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (340:9,32 [11] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (340:9,32 [11] CssSelectorTagHelperAttributes.cshtml) - Html - 1 TagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - href - HtmlAttributeValueStyle.SingleQuotes
+ HtmlAttributeValue - (317:9,9 [14] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (317:9,9 [14] CssSelectorTagHelperAttributes.cshtml) - Html - ~/?hello=world
+ CSharpExpressionAttributeValue - (331:9,23 [7] CssSelectorTagHelperAttributes.cshtml) -
+ IntermediateToken - (333:9,25 [5] CssSelectorTagHelperAttributes.cshtml) - CSharp - false
+ DefaultTagHelperExecute -
+ HtmlContent - (355:9,47 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (355:9,47 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (357:10,0 [42] CssSelectorTagHelperAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper2
+ PreallocatedTagHelperProperty - (370:10,13 [4] CssSelectorTagHelperAttributes.cshtml) - __tagHelperAttribute_4 - type - Type
+ PreallocatedTagHelperProperty - (370:10,13 [4] CssSelectorTagHelperAttributes.cshtml) - __tagHelperAttribute_4 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ DefaultTagHelperExecute -
+ HtmlContent - (399:10,42 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (399:10,42 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (401:11,0 [43] CssSelectorTagHelperAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper2
+ PreallocatedTagHelperProperty - (414:11,13 [5] CssSelectorTagHelperAttributes.cshtml) - __tagHelperAttribute_6 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ DefaultTagHelperExecute -
+ HtmlContent - (444:11,43 [2] CssSelectorTagHelperAttributes.cshtml)
+ IntermediateToken - (444:11,43 [2] CssSelectorTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (446:12,0 [45] CssSelectorTagHelperAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper2
+ PreallocatedTagHelperProperty - (459:12,13 [8] CssSelectorTagHelperAttributes.cshtml) - __tagHelperAttribute_7 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_8
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml
new file mode 100644
index 0000000000..5dcaeebdbf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml
@@ -0,0 +1,15 @@
+<div>
+ @for(int i = 1; i <= 10; i++) {
+ <p>This is item #@i</p>
+ }
+</div>
+
+<p>
+@(Foo(Bar.Baz))
+@Foo(@<p>Bar @baz Biz</p>)
+</p>
+
+@section Footer {
+ <p>Foo</p>
+ @bar
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.codegen.cs
new file mode 100644
index 0000000000..d30aea4b02
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.codegen.cs
@@ -0,0 +1,68 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DesignTime_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object Footer = null;
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+ for(int i = 1; i <= 10; i++) {
+
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+
+ }
+
+#line default
+#line hidden
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+__o = Foo(Bar.Baz);
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+__o = Foo(item => new Template(async(__razor_template_writer) => {
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+ __o = baz;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+ DefineSection("Footer", async(__razor_section_writer) => {
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml"
+__o = bar;
+
+#line default
+#line hidden
+ }
+ );
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.ir.txt
new file mode 100644
index 0000000000..95345bd918
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.ir.txt
@@ -0,0 +1,63 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DesignTime_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (173:11,9 [6] DesignTime.cshtml) - Footer
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [19] DesignTime.cshtml)
+ IntermediateToken - (0:0,0 [5] DesignTime.cshtml) - Html - <div>
+ IntermediateToken - (5:0,5 [14] DesignTime.cshtml) - Html - \n
+ CSharpCode - (20:1,13 [36] DesignTime.cshtml)
+ IntermediateToken - (20:1,13 [36] DesignTime.cshtml) - CSharp - for(int i = 1; i <= 10; i++) {\n
+ HtmlContent - (56:2,4 [17] DesignTime.cshtml)
+ IntermediateToken - (56:2,4 [3] DesignTime.cshtml) - Html - <p>
+ IntermediateToken - (59:2,7 [14] DesignTime.cshtml) - Html - This is item #
+ CSharpExpression - (74:2,22 [1] DesignTime.cshtml)
+ IntermediateToken - (74:2,22 [1] DesignTime.cshtml) - CSharp - i
+ HtmlContent - (75:2,23 [4] DesignTime.cshtml)
+ IntermediateToken - (75:2,23 [4] DesignTime.cshtml) - Html - </p>
+ CSharpCode - (79:2,27 [15] DesignTime.cshtml)
+ IntermediateToken - (79:2,27 [15] DesignTime.cshtml) - CSharp - \n }
+ HtmlContent - (94:3,13 [17] DesignTime.cshtml)
+ IntermediateToken - (94:3,13 [2] DesignTime.cshtml) - Html - \n
+ IntermediateToken - (96:4,0 [6] DesignTime.cshtml) - Html - </div>
+ IntermediateToken - (102:4,6 [4] DesignTime.cshtml) - Html - \n\n
+ IntermediateToken - (106:6,0 [3] DesignTime.cshtml) - Html - <p>
+ IntermediateToken - (109:6,3 [2] DesignTime.cshtml) - Html - \n
+ CSharpExpression - (113:7,2 [12] DesignTime.cshtml)
+ IntermediateToken - (113:7,2 [12] DesignTime.cshtml) - CSharp - Foo(Bar.Baz)
+ HtmlContent - (126:7,15 [2] DesignTime.cshtml)
+ IntermediateToken - (126:7,15 [2] DesignTime.cshtml) - Html - \n
+ CSharpExpression - (129:8,1 [23] DesignTime.cshtml)
+ IntermediateToken - (129:8,1 [4] DesignTime.cshtml) - CSharp - Foo(
+ Template - (134:8,6 [18] DesignTime.cshtml)
+ HtmlContent - (134:8,6 [7] DesignTime.cshtml)
+ IntermediateToken - (134:8,6 [3] DesignTime.cshtml) - Html - <p>
+ IntermediateToken - (137:8,9 [4] DesignTime.cshtml) - Html - Bar
+ CSharpExpression - (142:8,14 [3] DesignTime.cshtml)
+ IntermediateToken - (142:8,14 [3] DesignTime.cshtml) - CSharp - baz
+ HtmlContent - (145:8,17 [8] DesignTime.cshtml)
+ IntermediateToken - (145:8,17 [4] DesignTime.cshtml) - Html - Biz
+ IntermediateToken - (149:8,21 [4] DesignTime.cshtml) - Html - </p>
+ IntermediateToken - (153:8,25 [1] DesignTime.cshtml) - CSharp - )
+ HtmlContent - (154:8,26 [10] DesignTime.cshtml)
+ IntermediateToken - (154:8,26 [2] DesignTime.cshtml) - Html - \n
+ IntermediateToken - (156:9,0 [4] DesignTime.cshtml) - Html - </p>
+ IntermediateToken - (160:9,4 [4] DesignTime.cshtml) - Html - \n\n
+ Section - - Footer
+ HtmlContent - (181:11,17 [22] DesignTime.cshtml)
+ IntermediateToken - (181:11,17 [6] DesignTime.cshtml) - Html - \n
+ IntermediateToken - (187:12,4 [3] DesignTime.cshtml) - Html - <p>
+ IntermediateToken - (190:12,7 [3] DesignTime.cshtml) - Html - Foo
+ IntermediateToken - (193:12,10 [4] DesignTime.cshtml) - Html - </p>
+ IntermediateToken - (197:12,14 [6] DesignTime.cshtml) - Html - \n
+ CSharpExpression - (204:13,5 [3] DesignTime.cshtml)
+ IntermediateToken - (204:13,5 [3] DesignTime.cshtml) - CSharp - bar
+ HtmlContent - (207:13,8 [2] DesignTime.cshtml)
+ IntermediateToken - (207:13,8 [2] DesignTime.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.mappings.txt
new file mode 100644
index 0000000000..87ab943dfc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime_DesignTime.mappings.txt
@@ -0,0 +1,49 @@
+Source Location: (173:11,9 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|Footer|
+Generated Location: (401:10,22 [6] )
+|Footer|
+
+Source Location: (20:1,13 [36] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|for(int i = 1; i <= 10; i++) {
+ |
+Generated Location: (830:22,13 [36] )
+|for(int i = 1; i <= 10; i++) {
+ |
+
+Source Location: (74:2,22 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|i|
+Generated Location: (1007:28,22 [1] )
+|i|
+
+Source Location: (79:2,27 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|
+ }|
+Generated Location: (1155:33,27 [15] )
+|
+ }|
+
+Source Location: (113:7,2 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|Foo(Bar.Baz)|
+Generated Location: (1295:39,6 [12] )
+|Foo(Bar.Baz)|
+
+Source Location: (129:8,1 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|Foo(|
+Generated Location: (1433:44,6 [4] )
+|Foo(|
+
+Source Location: (142:8,14 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|baz|
+Generated Location: (1595:46,14 [3] )
+|baz|
+
+Source Location: (153:8,25 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|)|
+Generated Location: (1636:51,1 [1] )
+|)|
+
+Source Location: (204:13,5 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DesignTime.cshtml)
+|bar|
+Generated Location: (1836:57,6 [3] )
+|bar|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml
new file mode 100644
index 0000000000..369558994e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml
@@ -0,0 +1,7 @@
+@addTagHelper "*, TestAssembly"
+
+<p age="3" AGE="40" Age="500">
+ <input type="button" TYPE="checkbox" />
+ <input type="button" checked="true" type="checkbox" checked="false" />
+ <input type='button' checked="true" type=checkbox checked='true' type="checkbox" checked=true />
+</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..bb9a7ef103
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,57 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "button";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "button";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "button";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = 3;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..63264fc10d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,96 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] DuplicateAttributeTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] DuplicateAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [259] DuplicateAttributeTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (65:2,30 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (65:2,30 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (71:3,4 [39] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperProperty - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperHtmlAttribute - - TYPE - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (98:3,31 [8] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (98:3,31 [8] DuplicateAttributeTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperExecute -
+ HtmlContent - (110:3,43 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (110:3,43 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (116:4,4 [70] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperProperty - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperProperty - (146:4,34 [4] DuplicateAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (146:4,34 [4] DuplicateAttributeTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (158:4,46 [8] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (158:4,46 [8] DuplicateAttributeTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperHtmlAttribute - - checked - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (177:4,65 [5] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (177:4,65 [5] DuplicateAttributeTagHelpers.cshtml) - Html - false
+ DefaultTagHelperExecute -
+ HtmlContent - (186:4,74 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (186:4,74 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (192:5,4 [96] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperProperty - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - Html - button
+ DefaultTagHelperProperty - (222:5,34 [4] DuplicateAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (222:5,34 [4] DuplicateAttributeTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (233:5,45 [8] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (233:5,45 [8] DuplicateAttributeTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperHtmlAttribute - - checked - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (251:5,63 [4] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (251:5,63 [4] DuplicateAttributeTagHelpers.cshtml) - Html - true
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (263:5,75 [8] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (263:5,75 [8] DuplicateAttributeTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperHtmlAttribute - - checked - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (281:5,93 [4] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (281:5,93 [4] DuplicateAttributeTagHelpers.cshtml) - Html - true
+ DefaultTagHelperExecute -
+ HtmlContent - (288:5,100 [2] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (288:5,100 [2] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (43:2,8 [1] DuplicateAttributeTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (43:2,8 [1] DuplicateAttributeTagHelpers.cshtml) - CSharp - 3
+ DefaultTagHelperHtmlAttribute - - AGE - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (51:2,16 [2] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (51:2,16 [2] DuplicateAttributeTagHelpers.cshtml) - Html - 40
+ DefaultTagHelperHtmlAttribute - - Age - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (60:2,25 [3] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (60:2,25 [3] DuplicateAttributeTagHelpers.cshtml) - Html - 500
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..550a6a62a4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,20 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (686:13,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (146:4,34 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml)
+|true|
+Generated Location: (1882:33,42 [4] )
+|true|
+
+Source Location: (222:5,34 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml)
+|true|
+Generated Location: (2424:42,42 [4] )
+|true|
+
+Source Location: (43:2,8 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml)
+|3|
+Generated Location: (2694:48,33 [1] )
+|3|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..fd4e90095d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,146 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4dc2ea6fc4bd045c34a90867a6a72183a3d01323"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"4dc2ea6fc4bd045c34a90867a6a72183a3d01323", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "button", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("TYPE", new global::Microsoft.AspNetCore.Html.HtmlString("checkbox"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("checkbox"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("checked", new global::Microsoft.AspNetCore.Html.HtmlString("false"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "button", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("checked", new global::Microsoft.AspNetCore.Html.HtmlString("true"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("checked", new global::Microsoft.AspNetCore.Html.HtmlString("true"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_7 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("AGE", new global::Microsoft.AspNetCore.Html.HtmlString("40"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_8 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("Age", new global::Microsoft.AspNetCore.Html.HtmlString("500"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_6);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = 3;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_7);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_8);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..f2e84ead91
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateAttributeTagHelpers_Runtime.ir.txt
@@ -0,0 +1,69 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateAttributeTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - button - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - TYPE - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - checked - false - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_4 - type - button - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - checked - true - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_6 - checked - true - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_7 - AGE - 40 - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_8 - Age - 500 - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (35:2,0 [259] DuplicateAttributeTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (65:2,30 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (65:2,30 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (71:3,4 [39] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (84:3,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (110:3,43 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (110:3,43 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (116:4,4 [70] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (129:4,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (146:4,34 [4] DuplicateAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (146:4,34 [4] DuplicateAttributeTagHelpers.cshtml) - CSharp - true
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ DefaultTagHelperExecute -
+ HtmlContent - (186:4,74 [6] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (186:4,74 [6] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (192:5,4 [96] DuplicateAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_4 - type - Type
+ PreallocatedTagHelperProperty - (205:5,17 [6] DuplicateAttributeTagHelpers.cshtml) - __tagHelperAttribute_4 - type - Type
+ DefaultTagHelperProperty - (222:5,34 [4] DuplicateAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (222:5,34 [4] DuplicateAttributeTagHelpers.cshtml) - CSharp - true
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_6
+ DefaultTagHelperExecute -
+ HtmlContent - (288:5,100 [2] DuplicateAttributeTagHelpers.cshtml)
+ IntermediateToken - (288:5,100 [2] DuplicateAttributeTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (43:2,8 [1] DuplicateAttributeTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (43:2,8 [1] DuplicateAttributeTagHelpers.cshtml) - CSharp - 3
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_7
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_8
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml
new file mode 100644
index 0000000000..9963a14d5e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml
@@ -0,0 +1,3 @@
+@addTagHelper "*, TestAssembly"
+
+<input type="checkbox" checked="true" /> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.codegen.cs
new file mode 100644
index 0000000000..98078501de
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.codegen.cs
@@ -0,0 +1,38 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateTargetTagHelper_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper.Type = "checkbox";
+ __TestNamespace_CatchAllTagHelper.Type = __TestNamespace_InputTagHelper.Type;
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml"
+__TestNamespace_InputTagHelper.Checked = true;
+
+#line default
+#line hidden
+ __TestNamespace_CatchAllTagHelper.Checked = __TestNamespace_InputTagHelper.Checked;
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.ir.txt
new file mode 100644
index 0000000000..2ea133100c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.ir.txt
@@ -0,0 +1,32 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateTargetTagHelper_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] DuplicateTargetTagHelper.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] DuplicateTargetTagHelper.cshtml)
+ IntermediateToken - (31:0,31 [4] DuplicateTargetTagHelper.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [40] DuplicateTargetTagHelper.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (48:2,13 [8] DuplicateTargetTagHelper.cshtml)
+ IntermediateToken - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - type - string TestNamespace.CatchAllTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (48:2,13 [8] DuplicateTargetTagHelper.cshtml)
+ IntermediateToken - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - checked - bool TestNamespace.InputTagHelper.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - CSharp - true
+ DefaultTagHelperProperty - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - checked - bool TestNamespace.CatchAllTagHelper.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.mappings.txt
new file mode 100644
index 0000000000..800ab195ba
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml)
+|"*, TestAssembly"|
+Generated Location: (608:12,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (67:2,32 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml)
+|true|
+Generated Location: (1449:28,41 [4] )
+|true|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.codegen.cs
new file mode 100644
index 0000000000..6746458ed3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.codegen.cs
@@ -0,0 +1,65 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "97a60a6d99646ce1d67aab46447cc8f582f6f03a"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateTargetTagHelper_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"97a60a6d99646ce1d67aab46447cc8f582f6f03a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateTargetTagHelper_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "checkbox", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_CatchAllTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper.cshtml"
+__TestNamespace_InputTagHelper.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_CatchAllTagHelper.Checked = __TestNamespace_InputTagHelper.Checked;
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.ir.txt
new file mode 100644
index 0000000000..d86a4d2b8c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DuplicateTargetTagHelper_Runtime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DuplicateTargetTagHelper_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] DuplicateTargetTagHelper.cshtml)
+ IntermediateToken - (33:1,0 [2] DuplicateTargetTagHelper.cshtml) - Html - \n
+ TagHelper - (35:2,0 [40] DuplicateTargetTagHelper.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperProperty - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (48:2,13 [8] DuplicateTargetTagHelper.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - checked - bool TestNamespace.InputTagHelper.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - CSharp - true
+ DefaultTagHelperProperty - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - checked - bool TestNamespace.CatchAllTagHelper.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:2,32 [4] DuplicateTargetTagHelper.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml
new file mode 100644
index 0000000000..5e69ed1d81
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml
@@ -0,0 +1,14 @@
+@addTagHelper "*, TestAssembly"
+
+<input unbound="prefix @DateTime.Now" />
+
+<input unbound="@if (true) { @string.Empty } else { @false } suffix" />
+
+<input bound="prefix @DateTime.Now suffix" unbound="prefix @DateTime.Now suffix" />
+
+<input bound="@long.MinValue @if (true) { @string.Empty } else { @false } @int.MaxValue"
+ unbound="@long.MinValue @if (true) { @string.Empty } else { @false } @int.MaxValue" />
+
+<input unbound="@long.MinValue @DateTime.Now static content @int.MaxValue" />
+
+<input unbound="@if (true) { @string.Empty } else { @false }" /> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..dd5214d829
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,185 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = string.Empty;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = false;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Bound = string.Empty;
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = long.MinValue;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = string.Empty;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = false;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = int.MaxValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Bound = string.Empty;
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = long.MinValue;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = string.Empty;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = false;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = int.MaxValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = long.MinValue;
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = int.MaxValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = string.Empty;
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ __o = false;
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..76f7d9c916
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,133 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] DynamicAttributeTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [40] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (51:2,16 [6] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (51:2,16 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ CSharpExpressionAttributeValue - (57:2,22 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (59:2,24 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperExecute -
+ HtmlContent - (75:2,40 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (75:2,40 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (79:4,0 [71] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (95:4,16 [44] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (96:4,17 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (109:4,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (109:4,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (121:4,42 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (132:4,53 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (132:4,53 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (137:4,58 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ HtmlAttributeValue - (139:4,60 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (140:4,61 [6] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperExecute -
+ HtmlContent - (150:4,71 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (150:4,71 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (154:6,0 [83] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperProperty - (168:6,14 [27] DynamicAttributeTagHelpers.cshtml) - bound - string TestNamespace.InputTagHelper.Bound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (168:6,14 [7] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (168:6,14 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ IntermediateToken - (174:6,20 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (176:6,22 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (176:6,22 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlContent - (188:6,34 [7] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (188:6,34 [7] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (206:6,52 [6] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (206:6,52 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ CSharpExpressionAttributeValue - (212:6,58 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (214:6,60 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlAttributeValue - (226:6,72 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (227:6,73 [6] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperExecute -
+ HtmlContent - (237:6,83 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (237:6,83 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (241:8,0 [183] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperProperty - (255:8,14 [73] DynamicAttributeTagHelpers.cshtml) - bound - string TestNamespace.InputTagHelper.Bound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (256:8,15 [13] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (256:8,15 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ HtmlContent - (269:8,28 [1] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (269:8,28 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpCode - (271:8,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (271:8,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (284:8,43 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (284:8,43 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ CSharpCode - (296:8,55 [10] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (296:8,55 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (307:8,66 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (307:8,66 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ CSharpCode - (312:8,71 [2] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (312:8,71 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ HtmlContent - (314:8,73 [1] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (314:8,73 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (316:8,75 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (316:8,75 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (347:9,16 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (348:9,17 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ CSharpCodeAttributeValue - (361:9,30 [45] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (363:9,32 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (376:9,45 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (376:9,45 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (388:9,57 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (399:9,68 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (399:9,68 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (404:9,73 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ CSharpExpressionAttributeValue - (406:9,75 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (408:9,77 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperExecute -
+ HtmlContent - (424:9,93 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (424:9,93 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (428:11,0 [80] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (444:11,16 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (445:11,17 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ CSharpExpressionAttributeValue - (458:11,30 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (460:11,32 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlAttributeValue - (472:11,44 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (473:11,45 [6] DynamicAttributeTagHelpers.cshtml) - Html - static
+ HtmlAttributeValue - (479:11,51 [11] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (483:11,55 [7] DynamicAttributeTagHelpers.cshtml) - Html - content
+ CSharpExpressionAttributeValue - (490:11,62 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (492:11,64 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperExecute -
+ HtmlContent - (508:11,80 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (508:11,80 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (512:13,0 [64] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (528:13,16 [44] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (529:13,17 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (542:13,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (542:13,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (554:13,42 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (565:13,53 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (565:13,53 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (570:13,58 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..f2b45b216e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,155 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (518:11,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (59:2,24 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (1081:24,24 [12] )
+|DateTime.Now|
+
+Source Location: (96:4,17 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|if (true) { |
+Generated Location: (1349:30,17 [12] )
+|if (true) { |
+
+Source Location: (109:4,30 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|string.Empty|
+Generated Location: (1526:35,30 [12] )
+|string.Empty|
+
+Source Location: (121:4,42 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| } else { |
+Generated Location: (1716:40,42 [10] )
+| } else { |
+
+Source Location: (132:4,53 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|false|
+Generated Location: (1914:45,53 [5] )
+|false|
+
+Source Location: (137:4,58 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| }|
+Generated Location: (2113:50,58 [2] )
+| }|
+
+Source Location: (176:6,22 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (2375:56,22 [12] )
+|DateTime.Now|
+
+Source Location: (214:6,60 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (2649:62,60 [12] )
+|DateTime.Now|
+
+Source Location: (256:8,15 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|long.MinValue|
+Generated Location: (2915:68,15 [13] )
+|long.MinValue|
+
+Source Location: (271:8,30 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|if (true) { |
+Generated Location: (3094:73,30 [12] )
+|if (true) { |
+
+Source Location: (284:8,43 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|string.Empty|
+Generated Location: (3284:78,43 [12] )
+|string.Empty|
+
+Source Location: (296:8,55 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| } else { |
+Generated Location: (3487:83,55 [10] )
+| } else { |
+
+Source Location: (307:8,66 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|false|
+Generated Location: (3698:88,66 [5] )
+|false|
+
+Source Location: (312:8,71 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| }|
+Generated Location: (3910:93,71 [2] )
+| }|
+
+Source Location: (316:8,75 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|int.MaxValue|
+Generated Location: (4122:98,75 [12] )
+|int.MaxValue|
+
+Source Location: (348:9,17 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|long.MinValue|
+Generated Location: (4354:104,17 [13] )
+|long.MinValue|
+
+Source Location: (363:9,32 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|if (true) { |
+Generated Location: (4536:109,32 [12] )
+|if (true) { |
+
+Source Location: (376:9,45 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|string.Empty|
+Generated Location: (4729:114,45 [12] )
+|string.Empty|
+
+Source Location: (388:9,57 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| } else { |
+Generated Location: (4935:119,57 [10] )
+| } else { |
+
+Source Location: (399:9,68 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|false|
+Generated Location: (5149:124,68 [5] )
+|false|
+
+Source Location: (404:9,73 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| }|
+Generated Location: (5364:129,73 [2] )
+| }|
+
+Source Location: (408:9,77 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|int.MaxValue|
+Generated Location: (5579:134,77 [12] )
+|int.MaxValue|
+
+Source Location: (445:11,17 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|long.MinValue|
+Generated Location: (5848:140,17 [13] )
+|long.MinValue|
+
+Source Location: (460:11,32 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (6030:145,32 [12] )
+|DateTime.Now|
+
+Source Location: (492:11,64 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|int.MaxValue|
+Generated Location: (6243:150,64 [12] )
+|int.MaxValue|
+
+Source Location: (529:13,17 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|if (true) { |
+Generated Location: (6512:156,17 [12] )
+|if (true) { |
+
+Source Location: (542:13,30 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|string.Empty|
+Generated Location: (6690:161,30 [12] )
+|string.Empty|
+
+Source Location: (554:13,42 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| } else { |
+Generated Location: (6881:166,42 [10] )
+| } else { |
+
+Source Location: (565:13,53 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+|false|
+Generated Location: (7080:171,53 [5] )
+|false|
+
+Source Location: (570:13,58 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml)
+| }|
+Generated Location: (7280:176,58 [2] )
+| }|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..4371af8472
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,310 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "42f11f2c52ff2e658e61f6c5caace4347c07ca48"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"42f11f2c52ff2e658e61f6c5caace4347c07ca48", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_Runtime
+ {
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 51, "prefix", 51, 6, true);
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 57, DateTime.Now, 58, 13, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 95, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(string.Empty);
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(false);
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ PopWriter();
+ }
+ ), 95, 44, false);
+ AddHtmlAttributeValue(" ", 139, "suffix", 140, 7, true);
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("prefix ");
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ WriteLiteral(DateTime.Now);
+
+#line default
+#line hidden
+ WriteLiteral(" suffix");
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Bound = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("bound", __TestNamespace_InputTagHelper.Bound, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 3, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 206, "prefix", 206, 6, true);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 212, DateTime.Now, 213, 13, false);
+
+#line default
+#line hidden
+ AddHtmlAttributeValue(" ", 226, "suffix", 227, 7, true);
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginWriteTagHelperAttribute();
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ WriteLiteral(long.MinValue);
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ WriteLiteral(string.Empty);
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ WriteLiteral(false);
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ WriteLiteral(int.MaxValue);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Bound = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("bound", __TestNamespace_InputTagHelper.Bound, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 3, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue("", 347, long.MinValue, 347, 14, false);
+
+#line default
+#line hidden
+ AddHtmlAttributeValue(" ", 361, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(string.Empty);
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(false);
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ PopWriter();
+ }
+ ), 362, 44, false);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 406, int.MaxValue, 407, 13, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 5, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue("", 444, long.MinValue, 444, 14, false);
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 458, DateTime.Now, 459, 13, false);
+
+#line default
+#line hidden
+ AddHtmlAttributeValue(" ", 472, "static", 473, 7, true);
+ AddHtmlAttributeValue(" ", 479, "content", 483, 11, true);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+AddHtmlAttributeValue(" ", 490, int.MaxValue, 491, 13, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unbound", 1, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 528, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(string.Empty);
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ Write(false);
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ PopWriter();
+ }
+ ), 528, 44, false);
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..72a0832670
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/DynamicAttributeTagHelpers_Runtime.ir.txt
@@ -0,0 +1,127 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_DynamicAttributeTagHelpers_Runtime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] DynamicAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (35:2,0 [40] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (51:2,16 [6] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (51:2,16 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ CSharpExpressionAttributeValue - (57:2,22 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (59:2,24 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperExecute -
+ HtmlContent - (75:2,40 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (75:2,40 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (79:4,0 [71] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (95:4,16 [44] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (96:4,17 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (109:4,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (109:4,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (121:4,42 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (132:4,53 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (132:4,53 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (137:4,58 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ HtmlAttributeValue - (139:4,60 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (140:4,61 [6] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperExecute -
+ HtmlContent - (150:4,71 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (150:4,71 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (154:6,0 [83] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperProperty - (168:6,14 [27] DynamicAttributeTagHelpers.cshtml) - bound - string TestNamespace.InputTagHelper.Bound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (168:6,14 [7] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (168:6,14 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ IntermediateToken - (174:6,20 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (176:6,22 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (176:6,22 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlContent - (188:6,34 [7] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (188:6,34 [7] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (206:6,52 [6] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (206:6,52 [6] DynamicAttributeTagHelpers.cshtml) - Html - prefix
+ CSharpExpressionAttributeValue - (212:6,58 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (214:6,60 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlAttributeValue - (226:6,72 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (227:6,73 [6] DynamicAttributeTagHelpers.cshtml) - Html - suffix
+ DefaultTagHelperExecute -
+ HtmlContent - (237:6,83 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (237:6,83 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (241:8,0 [183] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperProperty - (255:8,14 [73] DynamicAttributeTagHelpers.cshtml) - bound - string TestNamespace.InputTagHelper.Bound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (256:8,15 [13] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (256:8,15 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ HtmlContent - (269:8,28 [1] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (269:8,28 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpCode - (271:8,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (271:8,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (284:8,43 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (284:8,43 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ CSharpCode - (296:8,55 [10] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (296:8,55 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (307:8,66 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (307:8,66 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ CSharpCode - (312:8,71 [2] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (312:8,71 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ HtmlContent - (314:8,73 [1] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (314:8,73 [1] DynamicAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (316:8,75 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (316:8,75 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (347:9,16 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (348:9,17 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ CSharpCodeAttributeValue - (361:9,30 [45] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (363:9,32 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (376:9,45 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (376:9,45 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (388:9,57 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (399:9,68 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (399:9,68 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (404:9,73 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ CSharpExpressionAttributeValue - (406:9,75 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (408:9,77 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperExecute -
+ HtmlContent - (424:9,93 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (424:9,93 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (428:11,0 [80] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (444:11,16 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (445:11,17 [13] DynamicAttributeTagHelpers.cshtml) - CSharp - long.MinValue
+ CSharpExpressionAttributeValue - (458:11,30 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (460:11,32 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlAttributeValue - (472:11,44 [7] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (473:11,45 [6] DynamicAttributeTagHelpers.cshtml) - Html - static
+ HtmlAttributeValue - (479:11,51 [11] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (483:11,55 [7] DynamicAttributeTagHelpers.cshtml) - Html - content
+ CSharpExpressionAttributeValue - (490:11,62 [14] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (492:11,64 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - int.MaxValue
+ DefaultTagHelperExecute -
+ HtmlContent - (508:11,80 [4] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (508:11,80 [4] DynamicAttributeTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (512:13,0 [64] DynamicAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (528:13,16 [44] DynamicAttributeTagHelpers.cshtml) -
+ IntermediateToken - (529:13,17 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - if (true) {
+ CSharpExpression - (542:13,30 [12] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (542:13,30 [12] DynamicAttributeTagHelpers.cshtml) - CSharp - string.Empty
+ IntermediateToken - (554:13,42 [10] DynamicAttributeTagHelpers.cshtml) - CSharp - } else {
+ CSharpExpression - (565:13,53 [5] DynamicAttributeTagHelpers.cshtml)
+ IntermediateToken - (565:13,53 [5] DynamicAttributeTagHelpers.cshtml) - CSharp - false
+ IntermediateToken - (570:13,58 [2] DynamicAttributeTagHelpers.cshtml) - CSharp - }
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml
new file mode 100644
index 0000000000..d68f666f72
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml
@@ -0,0 +1,8 @@
+@addTagHelper *, TestAssembly
+
+<div>
+ <input type= checked=""class="" />
+ <p age=''>
+ <input type=""checked= class="" />
+ </p>
+</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..669d7a19c6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,53 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = ;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = ;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = ;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..0b20997aff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.diagnostics.txt
@@ -0,0 +1,3 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ2008: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..ac2238b35e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,67 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] EmptyAttributeTagHelpers.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [15] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (29:0,29 [4] EmptyAttributeTagHelpers.cshtml) - Html - \n\n
+ IntermediateToken - (33:2,0 [5] EmptyAttributeTagHelpers.cshtml) - Html - <div>
+ IntermediateToken - (38:2,5 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (44:3,4 [34] EmptyAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperProperty - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperProperty - (66:3,26 [0] EmptyAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (66:3,26 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (74:3,34 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (74:3,34 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperExecute -
+ HtmlContent - (78:3,38 [6] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (78:3,38 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (84:4,4 [64] EmptyAttributeTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (94:4,14 [10] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (94:4,14 [10] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (104:5,8 [34] EmptyAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperProperty - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperProperty - (126:5,30 [0] EmptyAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (126:5,30 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (134:5,38 [0] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (134:5,38 [0] EmptyAttributeTagHelpers.cshtml) - Html -
+ DefaultTagHelperExecute -
+ HtmlContent - (138:5,42 [6] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (138:5,42 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (92:4,12 [0] EmptyAttributeTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.SingleQuotes
+ IntermediateToken - (92:4,12 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperExecute -
+ HtmlContent - (148:6,8 [8] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (148:6,8 [2] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (150:7,0 [6] EmptyAttributeTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..1f98a4c03f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,20 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml)
+|*, TestAssembly|
+Generated Location: (683:13,38 [15] )
+|*, TestAssembly|
+
+Source Location: (66:3,26 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml)
+||
+Generated Location: (1510:29,42 [0] )
+||
+
+Source Location: (126:5,30 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml)
+||
+Generated Location: (2038:38,42 [0] )
+||
+
+Source Location: (92:4,12 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml)
+||
+Generated Location: (2300:44,33 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..8f785ab50e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,114 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "9c86b0d6e2a590a85271afa26a21f39597a68e3f"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"9c86b0d6e2a590a85271afa26a21f39597a68e3f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString(""), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<div>\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = ;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = ;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml"
+__TestNamespace_PTagHelper.Age = ;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</div>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..0b20997aff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.diagnostics.txt
@@ -0,0 +1,3 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ2008: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..f8c39dee99
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers_Runtime.ir.txt
@@ -0,0 +1,51 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyAttributeTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [13] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (31:1,0 [2] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (33:2,0 [5] EmptyAttributeTagHelpers.cshtml) - Html - <div>
+ IntermediateToken - (38:2,5 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (44:3,4 [34] EmptyAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (56:3,16 [0] EmptyAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (66:3,26 [0] EmptyAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (66:3,26 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (78:3,38 [6] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (78:3,38 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (84:4,4 [64] EmptyAttributeTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (94:4,14 [10] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (94:4,14 [10] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (104:5,8 [34] EmptyAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (117:5,21 [0] EmptyAttributeTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (126:5,30 [0] EmptyAttributeTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (126:5,30 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (138:5,42 [6] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (138:5,42 [6] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (92:4,12 [0] EmptyAttributeTagHelpers.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.SingleQuotes
+ IntermediateToken - (92:4,12 [0] EmptyAttributeTagHelpers.cshtml) - CSharp -
+ DefaultTagHelperExecute -
+ HtmlContent - (148:6,8 [8] EmptyAttributeTagHelpers.cshtml)
+ IntermediateToken - (148:6,8 [2] EmptyAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (150:7,0 [6] EmptyAttributeTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml
new file mode 100644
index 0000000000..0366199cd5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml
@@ -0,0 +1,3 @@
+This is markup
+
+@{} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.codegen.cs
new file mode 100644
index 0000000000..6927c99f10
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.codegen.cs
@@ -0,0 +1,23 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.ir.txt
new file mode 100644
index 0000000000..1da8246eee
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyCodeBlock.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyCodeBlock.cshtml) - Html - This is markup\n\n
+ CSharpCode - (20:2,2 [0] EmptyCodeBlock.cshtml)
+ IntermediateToken - (20:2,2 [0] EmptyCodeBlock.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.mappings.txt
new file mode 100644
index 0000000000..be686c9435
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (20:2,2 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml)
+||
+Generated Location: (651:17,14 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.codegen.cs
new file mode 100644
index 0000000000..d7513d8023
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.codegen.cs
@@ -0,0 +1,19 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "fdc98942fed24e572b86269f89a808b0c606cef1"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"fdc98942fed24e572b86269f89a808b0c606cef1", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("This is markup\r\n\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.ir.txt
new file mode 100644
index 0000000000..75e7307e0f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyCodeBlock_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyCodeBlock_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyCodeBlock.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyCodeBlock.cshtml) - Html - This is markup\n\n
+ CSharpCode - (20:2,2 [0] EmptyCodeBlock.cshtml)
+ IntermediateToken - (20:2,2 [0] EmptyCodeBlock.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml
new file mode 100644
index 0000000000..6790c7eba2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml
@@ -0,0 +1,3 @@
+This is markup
+
+@() \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.codegen.cs
new file mode 100644
index 0000000000..15b5dea655
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.codegen.cs
@@ -0,0 +1,27 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml"
+__o = ;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.ir.txt
new file mode 100644
index 0000000000..cca09001e8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyExplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyExplicitExpression.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (20:2,2 [0] EmptyExplicitExpression.cshtml)
+ IntermediateToken - (20:2,2 [0] EmptyExplicitExpression.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.mappings.txt
new file mode 100644
index 0000000000..47eec8be51
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (20:2,2 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml)
+||
+Generated Location: (751:18,6 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.codegen.cs
new file mode 100644
index 0000000000..35d2af9843
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.codegen.cs
@@ -0,0 +1,24 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "25dc9cf13110b5af9a1ca31a8f02abdc45a37244"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"25dc9cf13110b5af9a1ca31a8f02abdc45a37244", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("This is markup\r\n\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression.cshtml"
+Write();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.ir.txt
new file mode 100644
index 0000000000..c3daa8feb5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyExplicitExpression_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyExplicitExpression_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyExplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyExplicitExpression.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (20:2,2 [0] EmptyExplicitExpression.cshtml)
+ IntermediateToken - (20:2,2 [0] EmptyExplicitExpression.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml
new file mode 100644
index 0000000000..021306da6b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml
@@ -0,0 +1,3 @@
+This is markup
+
+@! \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml
new file mode 100644
index 0000000000..a1db8cd602
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml
@@ -0,0 +1,3 @@
+@{
+ @
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.codegen.cs
new file mode 100644
index 0000000000..2f466f8132
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.codegen.cs
@@ -0,0 +1,31 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml"
+__o = ;
+
+#line default
+#line hidden
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..84ac278f6d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml(2,6): Error RZ1003: A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.ir.txt
new file mode 100644
index 0000000000..d167e2f6b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.ir.txt
@@ -0,0 +1,17 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (2:0,2 [6] EmptyImplicitExpressionInCode.cshtml) - CSharp - \n
+ CSharpExpression - (9:1,5 [0] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (9:1,5 [0] EmptyImplicitExpressionInCode.cshtml) - CSharp -
+ CSharpCode - (9:1,5 [2] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (9:1,5 [2] EmptyImplicitExpressionInCode.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.mappings.txt
new file mode 100644
index 0000000000..8fde4acc1b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_DesignTime.mappings.txt
@@ -0,0 +1,19 @@
+Source Location: (2:0,2 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml)
+|
+ |
+Generated Location: (666:17,14 [6] )
+|
+ |
+
+Source Location: (9:1,5 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml)
+||
+Generated Location: (785:20,6 [0] )
+||
+
+Source Location: (9:1,5 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml)
+|
+|
+Generated Location: (836:24,17 [2] )
+|
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.codegen.cs
new file mode 100644
index 0000000000..b8d77907e7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.codegen.cs
@@ -0,0 +1,23 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "bf754c5b319ea54f6c9636bd2815d4b47d11886d"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"bf754c5b319ea54f6c9636bd2815d4b47d11886d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml"
+Write();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..84ac278f6d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode.cshtml(2,6): Error RZ1003: A space or line break was encountered after the "@" character. Only valid identifiers, keywords, comments, "(" and "{" are valid at the start of a code block and they must occur immediately following "@" with no space in between.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.ir.txt
new file mode 100644
index 0000000000..b910f3841c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpressionInCode_Runtime.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpressionInCode_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (2:0,2 [6] EmptyImplicitExpressionInCode.cshtml) - CSharp - \n
+ CSharpExpression - (9:1,5 [0] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (9:1,5 [0] EmptyImplicitExpressionInCode.cshtml) - CSharp -
+ CSharpCode - (9:1,5 [2] EmptyImplicitExpressionInCode.cshtml)
+ IntermediateToken - (9:1,5 [2] EmptyImplicitExpressionInCode.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.codegen.cs
new file mode 100644
index 0000000000..971dd6bb45
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.codegen.cs
@@ -0,0 +1,27 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml"
+__o = ;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..5524460d0c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml(3,2): Error RZ1005: "!" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.ir.txt
new file mode 100644
index 0000000000..60189098dc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.ir.txt
@@ -0,0 +1,17 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyImplicitExpression.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (19:2,1 [0] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (19:2,1 [0] EmptyImplicitExpression.cshtml) - CSharp -
+ HtmlContent - (19:2,1 [1] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (19:2,1 [1] EmptyImplicitExpression.cshtml) - Html - !
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.mappings.txt
new file mode 100644
index 0000000000..356a4ebe7a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (19:2,1 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml)
+||
+Generated Location: (751:18,6 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.codegen.cs
new file mode 100644
index 0000000000..9b4be09572
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.codegen.cs
@@ -0,0 +1,25 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "4c215c8ff3e726be334183020106682e47cf8ace"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"4c215c8ff3e726be334183020106682e47cf8ace", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("This is markup\r\n\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml"
+Write();
+
+#line default
+#line hidden
+ WriteLiteral("!");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..5524460d0c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression.cshtml(3,2): Error RZ1005: "!" is not valid at the start of a code block. Only identifiers, keywords, comments, "(" and "{" are valid.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.ir.txt
new file mode 100644
index 0000000000..e4187049bb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyImplicitExpression_Runtime.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EmptyImplicitExpression_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [18] EmptyImplicitExpression.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (19:2,1 [0] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (19:2,1 [0] EmptyImplicitExpression.cshtml) - CSharp -
+ HtmlContent - (19:2,1 [1] EmptyImplicitExpression.cshtml)
+ IntermediateToken - (19:2,1 [1] EmptyImplicitExpression.cshtml) - Html - !
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml
new file mode 100644
index 0000000000..d949682156
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml
@@ -0,0 +1,11 @@
+@addTagHelper "*, TestAssembly"
+
+@{
+ var enumValue = MyEnum.MyValue;
+}
+
+<input value="@MyEnum.MyValue" />
+<input class="@MyEnum.MySecondValue" />
+<input value="MyValue" />
+<input value="MySecondValue" catch-all="MyValue"/>
+<input value="@enumValue" catch-all="@enumValue" />
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..db0d5933b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,79 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+
+ var enumValue = MyEnum.MyValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = MyEnum.MyValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+ __o = MyEnum.MySecondValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MyValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MySecondValue;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_CatchAllTagHelper.CatchAll = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MyValue;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = enumValue;
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_CatchAllTagHelper.CatchAll = enumValue;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..2418da2ba7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,74 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] EnumTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] EnumTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] EnumTagHelpers.cshtml) - Html - \n\n
+ CSharpCode - (37:2,2 [39] EnumTagHelpers.cshtml)
+ IntermediateToken - (37:2,2 [39] EnumTagHelpers.cshtml) - CSharp - \n var enumValue = MyEnum.MyValue;\n
+ HtmlContent - (79:5,0 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (79:5,0 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (81:6,0 [33] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (95:6,14 [15] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (96:6,15 [14] EnumTagHelpers.cshtml)
+ IntermediateToken - (96:6,15 [14] EnumTagHelpers.cshtml) - CSharp - MyEnum.MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (114:6,33 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (114:6,33 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (116:7,0 [39] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (130:7,14 [21] EnumTagHelpers.cshtml) -
+ IntermediateToken - (131:7,15 [20] EnumTagHelpers.cshtml) - CSharp - MyEnum.MySecondValue
+ DefaultTagHelperExecute -
+ HtmlContent - (155:7,39 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (155:7,39 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (157:8,0 [25] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (171:8,14 [7] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (171:8,14 [7] EnumTagHelpers.cshtml) - CSharp - MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (182:8,25 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (182:8,25 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (184:9,0 [50] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (198:9,14 [13] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (198:9,14 [13] EnumTagHelpers.cshtml) - CSharp - MySecondValue
+ DefaultTagHelperProperty - (224:9,40 [7] EnumTagHelpers.cshtml) - catch-all - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.CatchAllTagHelper.CatchAll - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (224:9,40 [7] EnumTagHelpers.cshtml) - CSharp - MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (234:9,50 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (234:9,50 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (236:10,0 [51] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (250:10,14 [10] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (251:10,15 [9] EnumTagHelpers.cshtml)
+ IntermediateToken - (251:10,15 [9] EnumTagHelpers.cshtml) - CSharp - enumValue
+ DefaultTagHelperProperty - (273:10,37 [10] EnumTagHelpers.cshtml) - catch-all - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.CatchAllTagHelper.CatchAll - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (274:10,38 [9] EnumTagHelpers.cshtml)
+ IntermediateToken - (274:10,38 [9] EnumTagHelpers.cshtml) - CSharp - enumValue
+ DefaultTagHelperExecute -
+ HtmlContent - (287:10,51 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (287:10,51 [2] EnumTagHelpers.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..948af33b62
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,49 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (598:12,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (37:2,2 [39] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|
+ var enumValue = MyEnum.MyValue;
+|
+Generated Location: (1024:24,2 [39] )
+|
+ var enumValue = MyEnum.MyValue;
+|
+
+Source Location: (96:6,15 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|MyEnum.MyValue|
+Generated Location: (1435:32,39 [14] )
+|MyEnum.MyValue|
+
+Source Location: (131:7,15 [20] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|MyEnum.MySecondValue|
+Generated Location: (1800:39,15 [20] )
+|MyEnum.MySecondValue|
+
+Source Location: (171:8,14 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|MyValue|
+Generated Location: (2288:46,132 [7] )
+|MyValue|
+
+Source Location: (198:9,14 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|MySecondValue|
+Generated Location: (2764:53,132 [13] )
+|MySecondValue|
+
+Source Location: (224:9,40 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|MyValue|
+Generated Location: (3040:58,138 [7] )
+|MyValue|
+
+Source Location: (251:10,15 [9] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|enumValue|
+Generated Location: (3423:65,39 [9] )
+|enumValue|
+
+Source Location: (274:10,38 [9] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml)
+|enumValue|
+Generated Location: (3602:70,45 [9] )
+|enumValue|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..47d1c91108
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,164 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a605351a30b7fef3db7e3f61a70a62e29a6badf8"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"a605351a30b7fef3db7e3f61a70a62e29a6badf8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_Runtime
+ {
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+
+ var enumValue = MyEnum.MyValue;
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = MyEnum.MyValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("value", __TestNamespace_InputTagHelper.Value, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 1, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+AddHtmlAttributeValue("", 130, MyEnum.MySecondValue, 130, 21, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MyValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("value", __TestNamespace_InputTagHelper.Value, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MySecondValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("value", __TestNamespace_InputTagHelper.Value, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_CatchAllTagHelper.CatchAll = global::Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum.MyValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("catch-all", __TestNamespace_CatchAllTagHelper.CatchAll, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_InputTagHelper.Value = enumValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("value", __TestNamespace_InputTagHelper.Value, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers.cshtml"
+__TestNamespace_CatchAllTagHelper.CatchAll = enumValue;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("catch-all", __TestNamespace_CatchAllTagHelper.CatchAll, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..e38db1bbaa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EnumTagHelpers_Runtime.ir.txt
@@ -0,0 +1,68 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EnumTagHelpers_Runtime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] EnumTagHelpers.cshtml) - Html - \n
+ CSharpCode - (37:2,2 [39] EnumTagHelpers.cshtml)
+ IntermediateToken - (37:2,2 [39] EnumTagHelpers.cshtml) - CSharp - \n var enumValue = MyEnum.MyValue;\n
+ HtmlContent - (79:5,0 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (79:5,0 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (81:6,0 [33] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (95:6,14 [15] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (96:6,15 [14] EnumTagHelpers.cshtml)
+ IntermediateToken - (96:6,15 [14] EnumTagHelpers.cshtml) - CSharp - MyEnum.MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (114:6,33 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (114:6,33 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (116:7,0 [39] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (130:7,14 [21] EnumTagHelpers.cshtml) -
+ IntermediateToken - (131:7,15 [20] EnumTagHelpers.cshtml) - CSharp - MyEnum.MySecondValue
+ DefaultTagHelperExecute -
+ HtmlContent - (155:7,39 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (155:7,39 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (157:8,0 [25] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (171:8,14 [7] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (171:8,14 [7] EnumTagHelpers.cshtml) - CSharp - MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (182:8,25 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (182:8,25 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (184:9,0 [50] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (198:9,14 [13] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (198:9,14 [13] EnumTagHelpers.cshtml) - CSharp - MySecondValue
+ DefaultTagHelperProperty - (224:9,40 [7] EnumTagHelpers.cshtml) - catch-all - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.CatchAllTagHelper.CatchAll - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (224:9,40 [7] EnumTagHelpers.cshtml) - CSharp - MyValue
+ DefaultTagHelperExecute -
+ HtmlContent - (234:9,50 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (234:9,50 [2] EnumTagHelpers.cshtml) - Html - \n
+ TagHelper - (236:10,0 [51] EnumTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperProperty - (250:10,14 [10] EnumTagHelpers.cshtml) - value - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.InputTagHelper.Value - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (251:10,15 [9] EnumTagHelpers.cshtml)
+ IntermediateToken - (251:10,15 [9] EnumTagHelpers.cshtml) - CSharp - enumValue
+ DefaultTagHelperProperty - (273:10,37 [10] EnumTagHelpers.cshtml) - catch-all - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestTagHelperDescriptors.MyEnum TestNamespace.CatchAllTagHelper.CatchAll - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (274:10,38 [9] EnumTagHelpers.cshtml)
+ IntermediateToken - (274:10,38 [9] EnumTagHelpers.cshtml) - CSharp - enumValue
+ DefaultTagHelperExecute -
+ HtmlContent - (287:10,51 [2] EnumTagHelpers.cshtml)
+ IntermediateToken - (287:10,51 [2] EnumTagHelpers.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml
new file mode 100644
index 0000000000..a7bc49af11
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml
@@ -0,0 +1,8 @@
+@addTagHelper *, TestAssembly
+
+<!div class="randomNonTagHelperAttribute">
+ <!p class="Hello World" @DateTime.Now>
+ <!input type="text" />
+ <!em>Not a TagHelper: </!em> <input type="@DateTime.Now" checked="true" />
+ </!p>
+</!div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..81fc96ba88
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,47 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+ __o = DateTime.Now;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = string.Empty;
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..9bc70b1439
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,69 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] EscapedTagHelpers.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [5] EscapedTagHelpers.cshtml)
+ IntermediateToken - (29:0,29 [4] EscapedTagHelpers.cshtml) - Html - \n\n
+ IntermediateToken - (33:2,0 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (35:2,2 [47] EscapedTagHelpers.cshtml)
+ IntermediateToken - (35:2,2 [3] EscapedTagHelpers.cshtml) - Html - div
+ IntermediateToken - (38:2,5 [36] EscapedTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (74:2,41 [1] EscapedTagHelpers.cshtml) - Html - >
+ IntermediateToken - (75:2,42 [6] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (81:3,4 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (83:3,6 [22] EscapedTagHelpers.cshtml)
+ IntermediateToken - (83:3,6 [1] EscapedTagHelpers.cshtml) - Html - p
+ IntermediateToken - (84:3,7 [20] EscapedTagHelpers.cshtml) - Html - class="Hello World"
+ IntermediateToken - (104:3,27 [1] EscapedTagHelpers.cshtml) - Html -
+ CSharpExpression - (106:3,29 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (106:3,29 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlContent - (118:3,41 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (118:3,41 [1] EscapedTagHelpers.cshtml) - Html - >
+ IntermediateToken - (119:3,42 [10] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (129:4,8 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (131:4,10 [31] EscapedTagHelpers.cshtml)
+ IntermediateToken - (131:4,10 [5] EscapedTagHelpers.cshtml) - Html - input
+ IntermediateToken - (136:4,15 [12] EscapedTagHelpers.cshtml) - Html - type="text"
+ IntermediateToken - (148:4,27 [3] EscapedTagHelpers.cshtml) - Html - />
+ IntermediateToken - (151:4,30 [10] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (161:5,8 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (163:5,10 [22] EscapedTagHelpers.cshtml)
+ IntermediateToken - (163:5,10 [3] EscapedTagHelpers.cshtml) - Html - em>
+ IntermediateToken - (166:5,13 [17] EscapedTagHelpers.cshtml) - Html - Not a TagHelper:
+ IntermediateToken - (183:5,30 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (186:5,33 [4] EscapedTagHelpers.cshtml)
+ IntermediateToken - (186:5,33 [3] EscapedTagHelpers.cshtml) - Html - em>
+ IntermediateToken - (189:5,36 [1] EscapedTagHelpers.cshtml) - Html -
+ TagHelper - (190:5,37 [45] EscapedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (203:5,50 [13] EscapedTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (204:5,51 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (204:5,51 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperProperty - (203:5,50 [13] EscapedTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (204:5,51 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (204:5,51 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperProperty - (227:5,74 [4] EscapedTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (227:5,74 [4] EscapedTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (235:5,82 [8] EscapedTagHelpers.cshtml)
+ IntermediateToken - (235:5,82 [6] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (241:6,4 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (244:6,7 [6] EscapedTagHelpers.cshtml)
+ IntermediateToken - (244:6,7 [2] EscapedTagHelpers.cshtml) - Html - p>
+ IntermediateToken - (246:6,9 [2] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (248:7,0 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (251:7,3 [4] EscapedTagHelpers.cshtml)
+ IntermediateToken - (251:7,3 [4] EscapedTagHelpers.cshtml) - Html - div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..32e64b25e5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,20 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml)
+|*, TestAssembly|
+Generated Location: (598:12,38 [15] )
+|*, TestAssembly|
+
+Source Location: (106:3,29 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (1053:24,29 [12] )
+|DateTime.Now|
+
+Source Location: (204:5,51 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml)
+|DateTime.Now|
+Generated Location: (1451:31,51 [12] )
+|DateTime.Now|
+
+Source Location: (227:5,74 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml)
+|true|
+Generated Location: (1818:38,74 [4] )
+|true|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..74ba222d6c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,83 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c1489e9dd98dc3e29bfbfd9a3f271ddec5134446"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"c1489e9dd98dc3e29bfbfd9a3f271ddec5134446", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_Runtime
+ {
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<");
+ WriteLiteral("div class=\"randomNonTagHelperAttribute\">\r\n <");
+ WriteLiteral("p class=\"Hello World\" ");
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+ Write(DateTime.Now);
+
+#line default
+#line hidden
+ WriteLiteral(">\r\n <");
+ WriteLiteral("input type=\"text\" />\r\n <");
+ WriteLiteral("em>Not a TagHelper: </");
+ WriteLiteral("em> ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+ WriteLiteral(DateTime.Now);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper.Type = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("type", __TestNamespace_InputTagHelper.Type, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n </");
+ WriteLiteral("p>\r\n</");
+ WriteLiteral("div>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..18242c571b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EscapedTagHelpers_Runtime.ir.txt
@@ -0,0 +1,63 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_EscapedTagHelpers_Runtime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [3] EscapedTagHelpers.cshtml)
+ IntermediateToken - (31:1,0 [2] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (33:2,0 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (35:2,2 [47] EscapedTagHelpers.cshtml)
+ IntermediateToken - (35:2,2 [3] EscapedTagHelpers.cshtml) - Html - div
+ IntermediateToken - (38:2,5 [36] EscapedTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (74:2,41 [1] EscapedTagHelpers.cshtml) - Html - >
+ IntermediateToken - (75:2,42 [6] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (81:3,4 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (83:3,6 [22] EscapedTagHelpers.cshtml)
+ IntermediateToken - (83:3,6 [1] EscapedTagHelpers.cshtml) - Html - p
+ IntermediateToken - (84:3,7 [20] EscapedTagHelpers.cshtml) - Html - class="Hello World"
+ IntermediateToken - (104:3,27 [1] EscapedTagHelpers.cshtml) - Html -
+ CSharpExpression - (106:3,29 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (106:3,29 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ HtmlContent - (118:3,41 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (118:3,41 [1] EscapedTagHelpers.cshtml) - Html - >
+ IntermediateToken - (119:3,42 [10] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (129:4,8 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (131:4,10 [31] EscapedTagHelpers.cshtml)
+ IntermediateToken - (131:4,10 [5] EscapedTagHelpers.cshtml) - Html - input
+ IntermediateToken - (136:4,15 [12] EscapedTagHelpers.cshtml) - Html - type="text"
+ IntermediateToken - (148:4,27 [3] EscapedTagHelpers.cshtml) - Html - />
+ IntermediateToken - (151:4,30 [10] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (161:5,8 [1] EscapedTagHelpers.cshtml) - Html - <
+ HtmlContent - (163:5,10 [22] EscapedTagHelpers.cshtml)
+ IntermediateToken - (163:5,10 [3] EscapedTagHelpers.cshtml) - Html - em>
+ IntermediateToken - (166:5,13 [17] EscapedTagHelpers.cshtml) - Html - Not a TagHelper:
+ IntermediateToken - (183:5,30 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (186:5,33 [4] EscapedTagHelpers.cshtml)
+ IntermediateToken - (186:5,33 [3] EscapedTagHelpers.cshtml) - Html - em>
+ IntermediateToken - (189:5,36 [1] EscapedTagHelpers.cshtml) - Html -
+ TagHelper - (190:5,37 [45] EscapedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (203:5,50 [13] EscapedTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (204:5,51 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (204:5,51 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperProperty - (203:5,50 [13] EscapedTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (204:5,51 [12] EscapedTagHelpers.cshtml)
+ IntermediateToken - (204:5,51 [12] EscapedTagHelpers.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperProperty - (227:5,74 [4] EscapedTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (227:5,74 [4] EscapedTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (235:5,82 [8] EscapedTagHelpers.cshtml)
+ IntermediateToken - (235:5,82 [6] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (241:6,4 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (244:6,7 [6] EscapedTagHelpers.cshtml)
+ IntermediateToken - (244:6,7 [2] EscapedTagHelpers.cshtml) - Html - p>
+ IntermediateToken - (246:6,9 [2] EscapedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (248:7,0 [2] EscapedTagHelpers.cshtml) - Html - </
+ HtmlContent - (251:7,3 [4] EscapedTagHelpers.cshtml)
+ IntermediateToken - (251:7,3 [4] EscapedTagHelpers.cshtml) - Html - div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml
new file mode 100644
index 0000000000..10730f1114
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml
@@ -0,0 +1 @@
+1 + 1 = @(1+1) \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml
new file mode 100644
index 0000000000..a0fdfc9a21
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml
@@ -0,0 +1,3 @@
+This is markup
+
+@( \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.codegen.cs
new file mode 100644
index 0000000000..3774cb8848
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.codegen.cs
@@ -0,0 +1,27 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml"
+__o = ;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..4e0bfb131d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml(3,2): Error RZ1006: The explicit expression block is missing a closing ")" character. Make sure you have a matching ")" character for all the "(" characters within this block, and that none of the ")" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.ir.txt
new file mode 100644
index 0000000000..947b28d727
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] ExplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (0:0,0 [18] ExplicitExpressionAtEOF.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (20:2,2 [0] ExplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (20:2,2 [0] ExplicitExpressionAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.mappings.txt
new file mode 100644
index 0000000000..5567e88c00
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (20:2,2 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml)
+||
+Generated Location: (751:18,6 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.codegen.cs
new file mode 100644
index 0000000000..2339c30ff9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.codegen.cs
@@ -0,0 +1,24 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e8e095026beaca454b3a8d02b1548fa001d08214"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"e8e095026beaca454b3a8d02b1548fa001d08214", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("This is markup\r\n\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml"
+Write();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..4e0bfb131d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF.cshtml(3,2): Error RZ1006: The explicit expression block is missing a closing ")" character. Make sure you have a matching ")" character for all the "(" characters within this block, and that none of the ")" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.ir.txt
new file mode 100644
index 0000000000..5f459014c8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionAtEOF_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionAtEOF_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] ExplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (0:0,0 [18] ExplicitExpressionAtEOF.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (20:2,2 [0] ExplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (20:2,2 [0] ExplicitExpressionAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml
new file mode 100644
index 0000000000..70d8cefd95
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml
@@ -0,0 +1 @@
+<div>@(@</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.codegen.cs
new file mode 100644
index 0000000000..e74c42e5cd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.codegen.cs
@@ -0,0 +1,29 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml"
+ __o = item => new Template(async(__razor_template_writer) => {
+}
+);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..16ad2a09d5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml(1,11): Error RZ1026: Encountered end tag "div" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml(1,7): Error RZ1006: The explicit expression block is missing a closing ")" character. Make sure you have a matching ")" character for all the "(" characters within this block, and that none of the ")" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.ir.txt
new file mode 100644
index 0000000000..f405093799
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.ir.txt
@@ -0,0 +1,18 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [5] ExplicitExpressionWithMarkup.cshtml)
+ IntermediateToken - (0:0,0 [5] ExplicitExpressionWithMarkup.cshtml) - Html - <div>
+ CSharpExpression - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ Template - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ HtmlContent - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ IntermediateToken - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml) - Html - </div>
+ IntermediateToken - (14:0,14 [0] ExplicitExpressionWithMarkup.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.mappings.txt
new file mode 100644
index 0000000000..228b0d53df
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml)
+||
+Generated Location: (825:20,1 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.codegen.cs
new file mode 100644
index 0000000000..7a1de2419b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.codegen.cs
@@ -0,0 +1,29 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "47d858755c07db489bd8824b7eaee760bb858bcb"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"47d858755c07db489bd8824b7eaee760bb858bcb", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<div>");
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml"
+ Write(item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("</div>");
+ PopWriter();
+}
+));
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..16ad2a09d5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml(1,11): Error RZ1026: Encountered end tag "div" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup.cshtml(1,7): Error RZ1006: The explicit expression block is missing a closing ")" character. Make sure you have a matching ")" character for all the "(" characters within this block, and that none of the ")" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.ir.txt
new file mode 100644
index 0000000000..dde86a08b2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpressionWithMarkup_Runtime.ir.txt
@@ -0,0 +1,13 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpressionWithMarkup_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [5] ExplicitExpressionWithMarkup.cshtml)
+ IntermediateToken - (0:0,0 [5] ExplicitExpressionWithMarkup.cshtml) - Html - <div>
+ CSharpExpression - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ Template - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ HtmlContent - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml)
+ IntermediateToken - (8:0,8 [6] ExplicitExpressionWithMarkup.cshtml) - Html - </div>
+ IntermediateToken - (14:0,14 [0] ExplicitExpressionWithMarkup.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.codegen.cs
new file mode 100644
index 0000000000..0dd6f9a38e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.codegen.cs
@@ -0,0 +1,27 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml"
+ __o = 1+1;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.ir.txt
new file mode 100644
index 0000000000..b2f22a261b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [8] ExplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [8] ExplicitExpression.cshtml) - Html - 1 + 1 =
+ CSharpExpression - (10:0,10 [3] ExplicitExpression.cshtml)
+ IntermediateToken - (10:0,10 [3] ExplicitExpression.cshtml) - CSharp - 1+1
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.mappings.txt
new file mode 100644
index 0000000000..22ed244ef6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (10:0,10 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml)
+|1+1|
+Generated Location: (745:18,10 [3] )
+|1+1|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.codegen.cs
new file mode 100644
index 0000000000..3f95cd0d28
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.codegen.cs
@@ -0,0 +1,24 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0fa6894c606c7426da1d8cacfbacf8be971c777f"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"0fa6894c606c7426da1d8cacfbacf8be971c777f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("1 + 1 = ");
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression.cshtml"
+ Write(1+1);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.ir.txt
new file mode 100644
index 0000000000..c1867efbb6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExplicitExpression_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExplicitExpression_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [8] ExplicitExpression.cshtml)
+ IntermediateToken - (0:0,0 [8] ExplicitExpression.cshtml) - Html - 1 + 1 =
+ CSharpExpression - (10:0,10 [3] ExplicitExpression.cshtml)
+ IntermediateToken - (10:0,10 [3] ExplicitExpression.cshtml) - CSharp - 1+1
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml
new file mode 100644
index 0000000000..a4d4caa007
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml
@@ -0,0 +1,16 @@
+@{
+ object foo = null;
+ string bar = "Foo";
+}
+
+@if(foo != null) {
+ @foo
+} else {
+ <p>Foo is Null!</p>
+}
+
+<p>
+@if(!String.IsNullOrEmpty(bar)) {
+ @(bar.Replace("F", "B"))
+}
+</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.codegen.cs
new file mode 100644
index 0000000000..29d0e48460
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.codegen.cs
@@ -0,0 +1,70 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+ object foo = null;
+ string bar = "Foo";
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+ if(foo != null) {
+
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+__o = foo;
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+} else {
+
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+ if(!String.IsNullOrEmpty(bar)) {
+
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+__o = bar.Replace("F", "B");
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.ir.txt
new file mode 100644
index 0000000000..763a344e8b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.ir.txt
@@ -0,0 +1,40 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [51] ExpressionsInCode.cshtml)
+ IntermediateToken - (2:0,2 [51] ExpressionsInCode.cshtml) - CSharp - \n object foo = null;\n string bar = "Foo";\n
+ HtmlContent - (56:4,0 [2] ExpressionsInCode.cshtml)
+ IntermediateToken - (56:4,0 [2] ExpressionsInCode.cshtml) - Html - \n
+ CSharpCode - (59:5,1 [23] ExpressionsInCode.cshtml)
+ IntermediateToken - (59:5,1 [23] ExpressionsInCode.cshtml) - CSharp - if(foo != null) {\n
+ CSharpExpression - (83:6,5 [3] ExpressionsInCode.cshtml)
+ IntermediateToken - (83:6,5 [3] ExpressionsInCode.cshtml) - CSharp - foo
+ CSharpCode - (86:6,8 [16] ExpressionsInCode.cshtml)
+ IntermediateToken - (86:6,8 [16] ExpressionsInCode.cshtml) - CSharp - \n} else {\n
+ HtmlContent - (102:8,4 [19] ExpressionsInCode.cshtml)
+ IntermediateToken - (102:8,4 [3] ExpressionsInCode.cshtml) - Html - <p>
+ IntermediateToken - (105:8,7 [12] ExpressionsInCode.cshtml) - Html - Foo is Null!
+ IntermediateToken - (117:8,19 [4] ExpressionsInCode.cshtml) - Html - </p>
+ CSharpCode - (121:8,23 [3] ExpressionsInCode.cshtml)
+ IntermediateToken - (121:8,23 [3] ExpressionsInCode.cshtml) - CSharp - \n}
+ HtmlContent - (124:9,1 [9] ExpressionsInCode.cshtml)
+ IntermediateToken - (124:9,1 [4] ExpressionsInCode.cshtml) - Html - \n\n
+ IntermediateToken - (128:11,0 [3] ExpressionsInCode.cshtml) - Html - <p>
+ IntermediateToken - (131:11,3 [2] ExpressionsInCode.cshtml) - Html - \n
+ CSharpCode - (134:12,1 [38] ExpressionsInCode.cshtml)
+ IntermediateToken - (134:12,1 [38] ExpressionsInCode.cshtml) - CSharp - if(!String.IsNullOrEmpty(bar)) {\n
+ CSharpExpression - (174:13,6 [21] ExpressionsInCode.cshtml)
+ IntermediateToken - (174:13,6 [21] ExpressionsInCode.cshtml) - CSharp - bar.Replace("F", "B")
+ CSharpCode - (196:13,28 [3] ExpressionsInCode.cshtml)
+ IntermediateToken - (196:13,28 [3] ExpressionsInCode.cshtml) - CSharp - \n}
+ HtmlContent - (199:14,1 [6] ExpressionsInCode.cshtml)
+ IntermediateToken - (199:14,1 [2] ExpressionsInCode.cshtml) - Html - \n
+ IntermediateToken - (201:15,0 [4] ExpressionsInCode.cshtml) - Html - </p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.mappings.txt
new file mode 100644
index 0000000000..5928a833f2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_DesignTime.mappings.txt
@@ -0,0 +1,58 @@
+Source Location: (2:0,2 [51] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|
+ object foo = null;
+ string bar = "Foo";
+|
+Generated Location: (735:18,2 [51] )
+|
+ object foo = null;
+ string bar = "Foo";
+|
+
+Source Location: (59:5,1 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|if(foo != null) {
+ |
+Generated Location: (911:25,1 [23] )
+|if(foo != null) {
+ |
+
+Source Location: (83:6,5 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|foo|
+Generated Location: (1066:31,6 [3] )
+|foo|
+
+Source Location: (86:6,8 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|
+} else {
+ |
+Generated Location: (1204:36,8 [16] )
+|
+} else {
+ |
+
+Source Location: (121:8,23 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|
+}|
+Generated Location: (1369:43,23 [3] )
+|
+}|
+
+Source Location: (134:12,1 [38] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|if(!String.IsNullOrEmpty(bar)) {
+ |
+Generated Location: (1500:49,1 [38] )
+|if(!String.IsNullOrEmpty(bar)) {
+ |
+
+Source Location: (174:13,6 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|bar.Replace("F", "B")|
+Generated Location: (1671:55,6 [21] )
+|bar.Replace("F", "B")|
+
+Source Location: (196:13,28 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml)
+|
+}|
+Generated Location: (1848:60,28 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.codegen.cs
new file mode 100644
index 0000000000..0196ab0af9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.codegen.cs
@@ -0,0 +1,68 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3ccb5b16f61b84dd82d7402e4a17870a39d09ca9"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"3ccb5b16f61b84dd82d7402e4a17870a39d09ca9", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+ object foo = null;
+ string bar = "Foo";
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+ if(foo != null) {
+
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+Write(foo);
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+} else {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Foo is Null!</p>\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n<p>\r\n");
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+ if(!String.IsNullOrEmpty(bar)) {
+
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+Write(bar.Replace("F", "B"));
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode.cshtml"
+
+}
+
+#line default
+#line hidden
+ WriteLiteral("</p>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.ir.txt
new file mode 100644
index 0000000000..d87e4b1d61
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ExpressionsInCode_Runtime.ir.txt
@@ -0,0 +1,36 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ExpressionsInCode_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [51] ExpressionsInCode.cshtml)
+ IntermediateToken - (2:0,2 [51] ExpressionsInCode.cshtml) - CSharp - \n object foo = null;\n string bar = "Foo";\n
+ HtmlContent - (56:4,0 [2] ExpressionsInCode.cshtml)
+ IntermediateToken - (56:4,0 [2] ExpressionsInCode.cshtml) - Html - \n
+ CSharpCode - (59:5,1 [23] ExpressionsInCode.cshtml)
+ IntermediateToken - (59:5,1 [23] ExpressionsInCode.cshtml) - CSharp - if(foo != null) {\n
+ CSharpExpression - (83:6,5 [3] ExpressionsInCode.cshtml)
+ IntermediateToken - (83:6,5 [3] ExpressionsInCode.cshtml) - CSharp - foo
+ CSharpCode - (86:6,8 [12] ExpressionsInCode.cshtml)
+ IntermediateToken - (86:6,8 [12] ExpressionsInCode.cshtml) - CSharp - \n} else {\n
+ HtmlContent - (98:8,0 [25] ExpressionsInCode.cshtml)
+ IntermediateToken - (98:8,0 [4] ExpressionsInCode.cshtml) - Html -
+ IntermediateToken - (102:8,4 [3] ExpressionsInCode.cshtml) - Html - <p>
+ IntermediateToken - (105:8,7 [12] ExpressionsInCode.cshtml) - Html - Foo is Null!
+ IntermediateToken - (117:8,19 [4] ExpressionsInCode.cshtml) - Html - </p>
+ IntermediateToken - (121:8,23 [2] ExpressionsInCode.cshtml) - Html - \n
+ CSharpCode - (123:9,0 [3] ExpressionsInCode.cshtml)
+ IntermediateToken - (123:9,0 [3] ExpressionsInCode.cshtml) - CSharp - }\n
+ HtmlContent - (126:10,0 [7] ExpressionsInCode.cshtml)
+ IntermediateToken - (126:10,0 [2] ExpressionsInCode.cshtml) - Html - \n
+ IntermediateToken - (128:11,0 [3] ExpressionsInCode.cshtml) - Html - <p>
+ IntermediateToken - (131:11,3 [2] ExpressionsInCode.cshtml) - Html - \n
+ CSharpCode - (134:12,1 [38] ExpressionsInCode.cshtml)
+ IntermediateToken - (134:12,1 [38] ExpressionsInCode.cshtml) - CSharp - if(!String.IsNullOrEmpty(bar)) {\n
+ CSharpExpression - (174:13,6 [21] ExpressionsInCode.cshtml)
+ IntermediateToken - (174:13,6 [21] ExpressionsInCode.cshtml) - CSharp - bar.Replace("F", "B")
+ CSharpCode - (196:13,28 [5] ExpressionsInCode.cshtml)
+ IntermediateToken - (196:13,28 [5] ExpressionsInCode.cshtml) - CSharp - \n}\n
+ HtmlContent - (201:15,0 [4] ExpressionsInCode.cshtml)
+ IntermediateToken - (201:15,0 [4] ExpressionsInCode.cshtml) - Html - </p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml
new file mode 100644
index 0000000000..5d06b37224
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml
@@ -0,0 +1,12 @@
+@functions {
+
+}
+
+@functions {
+ Random _rand = new Random();
+ private int RandomInt() {
+ return _rand.Next();
+ }
+}
+
+Here's a random number: @RandomInt() \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml
new file mode 100644
index 0000000000..6b3de50b2c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml
@@ -0,0 +1,7 @@
+
+
+ @functions{
+string foo(string input) {
+ return input + "!";
+}
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.codegen.cs
new file mode 100644
index 0000000000..11a32e14ea
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.codegen.cs
@@ -0,0 +1,30 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml"
+
+string foo(string input) {
+ return input + "!";
+}
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.ir.txt
new file mode 100644
index 0000000000..f460329dab
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [5] FunctionsBlockMinimal.cshtml)
+ IntermediateToken - (0:0,0 [5] FunctionsBlockMinimal.cshtml) - Html - \n\n
+ CSharpCode - (16:2,12 [55] FunctionsBlockMinimal.cshtml)
+ IntermediateToken - (16:2,12 [55] FunctionsBlockMinimal.cshtml) - CSharp - \nstring foo(string input) {\n return input + "!";\n}\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.mappings.txt
new file mode 100644
index 0000000000..b5c82b85e4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_DesignTime.mappings.txt
@@ -0,0 +1,13 @@
+Source Location: (16:2,12 [55] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml)
+|
+string foo(string input) {
+ return input + "!";
+}
+|
+Generated Location: (805:20,15 [55] )
+|
+string foo(string input) {
+ return input + "!";
+}
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.codegen.cs
new file mode 100644
index 0000000000..ebaea72b8d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.codegen.cs
@@ -0,0 +1,27 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5ba3477b8f10b5207bb9f610499189ac0d50aaa0"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5ba3477b8f10b5207bb9f610499189ac0d50aaa0", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n\r\n");
+ }
+ #pragma warning restore 1998
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal.cshtml"
+
+string foo(string input) {
+ return input + "!";
+}
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.ir.txt
new file mode 100644
index 0000000000..2d4242e8c4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlockMinimal_Runtime.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlockMinimal_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [4] FunctionsBlockMinimal.cshtml)
+ IntermediateToken - (0:0,0 [4] FunctionsBlockMinimal.cshtml) - Html - \n\n
+ CSharpCode - (4:2,0 [1] FunctionsBlockMinimal.cshtml)
+ IntermediateToken - (4:2,0 [1] FunctionsBlockMinimal.cshtml) - CSharp -
+ CSharpCode - (16:2,12 [55] FunctionsBlockMinimal.cshtml)
+ IntermediateToken - (16:2,12 [55] FunctionsBlockMinimal.cshtml) - CSharp - \nstring foo(string input) {\n return input + "!";\n}\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ac6848c885
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.codegen.cs
@@ -0,0 +1,39 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml"
+ __o = RandomInt();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+
+
+
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml"
+
+ Random _rand = new Random();
+ private int RandomInt() {
+ return _rand.Next();
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.ir.txt
new file mode 100644
index 0000000000..e71b8ed6a9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.ir.txt
@@ -0,0 +1,21 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (17:2,1 [4] FunctionsBlock.cshtml)
+ IntermediateToken - (17:2,1 [4] FunctionsBlock.cshtml) - Html - \n\n
+ HtmlContent - (138:9,1 [28] FunctionsBlock.cshtml)
+ IntermediateToken - (138:9,1 [28] FunctionsBlock.cshtml) - Html - \n\nHere's a random number:
+ CSharpExpression - (167:11,25 [11] FunctionsBlock.cshtml)
+ IntermediateToken - (167:11,25 [11] FunctionsBlock.cshtml) - CSharp - RandomInt()
+ CSharpCode - (12:0,12 [4] FunctionsBlock.cshtml)
+ IntermediateToken - (12:0,12 [4] FunctionsBlock.cshtml) - CSharp - \n\n
+ CSharpCode - (33:4,12 [104] FunctionsBlock.cshtml)
+ IntermediateToken - (33:4,12 [104] FunctionsBlock.cshtml) - CSharp - \n Random _rand = new Random();\n private int RandomInt() {\n return _rand.Next();\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.mappings.txt
new file mode 100644
index 0000000000..91a2fbde86
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_DesignTime.mappings.txt
@@ -0,0 +1,29 @@
+Source Location: (167:11,25 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml)
+|RandomInt()|
+Generated Location: (753:18,25 [11] )
+|RandomInt()|
+
+Source Location: (12:0,12 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml)
+|
+
+|
+Generated Location: (867:24,20 [4] )
+|
+
+|
+
+Source Location: (33:4,12 [104] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml)
+|
+ Random _rand = new Random();
+ private int RandomInt() {
+ return _rand.Next();
+ }
+|
+Generated Location: (975:28,12 [104] )
+|
+ Random _rand = new Random();
+ private int RandomInt() {
+ return _rand.Next();
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.codegen.cs
new file mode 100644
index 0000000000..06b4c1f0d2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.codegen.cs
@@ -0,0 +1,34 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e6a053bfeb65ba3e17885a8ae1523f28a3483258"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"e6a053bfeb65ba3e17885a8ae1523f28a3483258", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\nHere\'s a random number: ");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml"
+ Write(RandomInt());
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock.cshtml"
+
+ Random _rand = new Random();
+ private int RandomInt() {
+ return _rand.Next();
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.ir.txt
new file mode 100644
index 0000000000..4b05dbcc3d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/FunctionsBlock_Runtime.ir.txt
@@ -0,0 +1,16 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_FunctionsBlock_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (19:3,0 [2] FunctionsBlock.cshtml)
+ IntermediateToken - (19:3,0 [2] FunctionsBlock.cshtml) - Html - \n
+ HtmlContent - (140:10,0 [26] FunctionsBlock.cshtml)
+ IntermediateToken - (140:10,0 [26] FunctionsBlock.cshtml) - Html - \nHere's a random number:
+ CSharpExpression - (167:11,25 [11] FunctionsBlock.cshtml)
+ IntermediateToken - (167:11,25 [11] FunctionsBlock.cshtml) - CSharp - RandomInt()
+ CSharpCode - (12:0,12 [4] FunctionsBlock.cshtml)
+ IntermediateToken - (12:0,12 [4] FunctionsBlock.cshtml) - CSharp - \n\n
+ CSharpCode - (33:4,12 [104] FunctionsBlock.cshtml)
+ IntermediateToken - (33:4,12 [104] FunctionsBlock.cshtml) - CSharp - \n Random _rand = new Random();\n private int RandomInt() {\n return _rand.Next();\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml
new file mode 100644
index 0000000000..a6addbe97c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml
@@ -0,0 +1,3 @@
+@{
+ @@Da
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.codegen.cs
new file mode 100644
index 0000000000..77d9135c5a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.codegen.cs
@@ -0,0 +1,29 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml"
+ @Da
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.ir.txt
new file mode 100644
index 0000000000..6c3f2a9d41
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] HiddenSpansInCode.cshtml)
+ IntermediateToken - (2:0,2 [6] HiddenSpansInCode.cshtml) - CSharp - \n
+ CSharpCode - (9:1,5 [5] HiddenSpansInCode.cshtml)
+ IntermediateToken - (9:1,5 [5] HiddenSpansInCode.cshtml) - CSharp - @Da\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.mappings.txt
new file mode 100644
index 0000000000..e56c1f5b1f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_DesignTime.mappings.txt
@@ -0,0 +1,14 @@
+Source Location: (2:0,2 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml)
+|
+ |
+Generated Location: (654:17,14 [6] )
+|
+ |
+
+Source Location: (9:1,5 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml)
+|@Da
+|
+Generated Location: (760:20,5 [5] )
+|@Da
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.codegen.cs
new file mode 100644
index 0000000000..11ba8f037b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.codegen.cs
@@ -0,0 +1,23 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "9bc7458ab052e80d9c977bfce0f0c7e8aef0d80f"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"9bc7458ab052e80d9c977bfce0f0c7e8aef0d80f", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode.cshtml"
+ @Da
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.ir.txt
new file mode 100644
index 0000000000..92fc13fef7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HiddenSpansInCode_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HiddenSpansInCode_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] HiddenSpansInCode.cshtml)
+ IntermediateToken - (2:0,2 [6] HiddenSpansInCode.cshtml) - CSharp - \n
+ CSharpCode - (9:1,5 [5] HiddenSpansInCode.cshtml)
+ IntermediateToken - (9:1,5 [5] HiddenSpansInCode.cshtml) - CSharp - @Da\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml
new file mode 100644
index 0000000000..6a99437910
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml
@@ -0,0 +1,2 @@
+<!-- " -->
+<img src="~/images/submit.png" /> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.codegen.cs
new file mode 100644
index 0000000000..6add10d801
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.codegen.cs
@@ -0,0 +1,22 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt
new file mode 100644
index 0000000000..4523eae7a3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.ir.txt
@@ -0,0 +1,19 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Double.cshtml)
+ IntermediateToken - (0:0,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - <!--
+ IntermediateToken - (4:0,4 [3] HtmlCommentWithQuote_Double.cshtml) - Html - "
+ IntermediateToken - (7:0,7 [3] HtmlCommentWithQuote_Double.cshtml) - Html - -->
+ IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Double.cshtml) - Html - \n
+ IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - <img
+ IntermediateToken - (16:1,4 [26] HtmlCommentWithQuote_Double.cshtml) - Html - src="~/images/submit.png"
+ IntermediateToken - (42:1,30 [3] HtmlCommentWithQuote_Double.cshtml) - Html - />
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.mappings.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_DesignTime.mappings.txt
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.codegen.cs
new file mode 100644
index 0000000000..fb924e6327
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.codegen.cs
@@ -0,0 +1,19 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "520aebbcdbdb163b131356be8f3aef0eb0809c47"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"520aebbcdbdb163b131356be8f3aef0eb0809c47", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<!-- \" -->\r\n<img src=\"~/images/submit.png\" />");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt
new file mode 100644
index 0000000000..046cad8407
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Double_Runtime.ir.txt
@@ -0,0 +1,14 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Double_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Double.cshtml)
+ IntermediateToken - (0:0,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - <!--
+ IntermediateToken - (4:0,4 [3] HtmlCommentWithQuote_Double.cshtml) - Html - "
+ IntermediateToken - (7:0,7 [3] HtmlCommentWithQuote_Double.cshtml) - Html - -->
+ IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Double.cshtml) - Html - \n
+ IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Double.cshtml) - Html - <img
+ IntermediateToken - (16:1,4 [26] HtmlCommentWithQuote_Double.cshtml) - Html - src="~/images/submit.png"
+ IntermediateToken - (42:1,30 [3] HtmlCommentWithQuote_Double.cshtml) - Html - />
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml
new file mode 100644
index 0000000000..dc1b21a546
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml
@@ -0,0 +1,2 @@
+<!-- ' -->
+<img src="~/images/submit.png" /> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.codegen.cs
new file mode 100644
index 0000000000..e20af5e1ca
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.codegen.cs
@@ -0,0 +1,22 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt
new file mode 100644
index 0000000000..8b5f5b3ed5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.ir.txt
@@ -0,0 +1,19 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Single.cshtml)
+ IntermediateToken - (0:0,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - <!--
+ IntermediateToken - (4:0,4 [3] HtmlCommentWithQuote_Single.cshtml) - Html - '
+ IntermediateToken - (7:0,7 [3] HtmlCommentWithQuote_Single.cshtml) - Html - -->
+ IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Single.cshtml) - Html - \n
+ IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - <img
+ IntermediateToken - (16:1,4 [26] HtmlCommentWithQuote_Single.cshtml) - Html - src="~/images/submit.png"
+ IntermediateToken - (42:1,30 [3] HtmlCommentWithQuote_Single.cshtml) - Html - />
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.mappings.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_DesignTime.mappings.txt
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.codegen.cs
new file mode 100644
index 0000000000..1bce0936db
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.codegen.cs
@@ -0,0 +1,19 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2080c7f4c5de3e5e7f309c11a6be5c5e8d86e75a"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2080c7f4c5de3e5e7f309c11a6be5c5e8d86e75a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<!-- \' -->\r\n<img src=\"~/images/submit.png\" />");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt
new file mode 100644
index 0000000000..8596f51503
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/HtmlCommentWithQuote_Single_Runtime.ir.txt
@@ -0,0 +1,14 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_HtmlCommentWithQuote_Single_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [45] HtmlCommentWithQuote_Single.cshtml)
+ IntermediateToken - (0:0,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - <!--
+ IntermediateToken - (4:0,4 [3] HtmlCommentWithQuote_Single.cshtml) - Html - '
+ IntermediateToken - (7:0,7 [3] HtmlCommentWithQuote_Single.cshtml) - Html - -->
+ IntermediateToken - (10:0,10 [2] HtmlCommentWithQuote_Single.cshtml) - Html - \n
+ IntermediateToken - (12:1,0 [4] HtmlCommentWithQuote_Single.cshtml) - Html - <img
+ IntermediateToken - (16:1,4 [26] HtmlCommentWithQuote_Single.cshtml) - Html - src="~/images/submit.png"
+ IntermediateToken - (42:1,30 [3] HtmlCommentWithQuote_Single.cshtml) - Html - />
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml
new file mode 100644
index 0000000000..dcce7fa572
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml
@@ -0,0 +1,3 @@
+@for(int i = 1; i <= 10; i++) {
+ <p>This is item #@i</p>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml
new file mode 100644
index 0000000000..365d20e003
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml
@@ -0,0 +1,3 @@
+This is markup
+
+@ \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.codegen.cs
new file mode 100644
index 0000000000..256186f057
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.codegen.cs
@@ -0,0 +1,27 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml"
+__o = ;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..e2a8c29095
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml(3,2): Error RZ1004: End-of-file was found after the "@" character. "@" must be followed by a valid code block. If you want to output an "@", escape it using the sequence: "@@"
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.ir.txt
new file mode 100644
index 0000000000..19598b5d7e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] ImplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (0:0,0 [18] ImplicitExpressionAtEOF.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (19:2,1 [0] ImplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (19:2,1 [0] ImplicitExpressionAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.mappings.txt
new file mode 100644
index 0000000000..9f93c42b2d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (19:2,1 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml)
+||
+Generated Location: (751:18,6 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.codegen.cs
new file mode 100644
index 0000000000..5c6798e2de
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.codegen.cs
@@ -0,0 +1,24 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "94cd2b5a8281fc76002fc745485949cf3952a058"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"94cd2b5a8281fc76002fc745485949cf3952a058", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("This is markup\r\n\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml"
+Write();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..e2a8c29095
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF.cshtml(3,2): Error RZ1004: End-of-file was found after the "@" character. "@" must be followed by a valid code block. If you want to output an "@", escape it using the sequence: "@@"
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.ir.txt
new file mode 100644
index 0000000000..b2ac3e3520
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpressionAtEOF_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpressionAtEOF_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [18] ImplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (0:0,0 [18] ImplicitExpressionAtEOF.cshtml) - Html - This is markup\n\n
+ CSharpExpression - (19:2,1 [0] ImplicitExpressionAtEOF.cshtml)
+ IntermediateToken - (19:2,1 [0] ImplicitExpressionAtEOF.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.codegen.cs
new file mode 100644
index 0000000000..80dc9a12e4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.codegen.cs
@@ -0,0 +1,39 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+ for(int i = 1; i <= 10; i++) {
+
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.ir.txt
new file mode 100644
index 0000000000..83c51c28fc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.ir.txt
@@ -0,0 +1,22 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [36] ImplicitExpression.cshtml)
+ IntermediateToken - (1:0,1 [36] ImplicitExpression.cshtml) - CSharp - for(int i = 1; i <= 10; i++) {\n
+ HtmlContent - (37:1,4 [17] ImplicitExpression.cshtml)
+ IntermediateToken - (37:1,4 [3] ImplicitExpression.cshtml) - Html - <p>
+ IntermediateToken - (40:1,7 [14] ImplicitExpression.cshtml) - Html - This is item #
+ CSharpExpression - (55:1,22 [1] ImplicitExpression.cshtml)
+ IntermediateToken - (55:1,22 [1] ImplicitExpression.cshtml) - CSharp - i
+ HtmlContent - (56:1,23 [4] ImplicitExpression.cshtml)
+ IntermediateToken - (56:1,23 [4] ImplicitExpression.cshtml) - Html - </p>
+ CSharpCode - (60:1,27 [3] ImplicitExpression.cshtml)
+ IntermediateToken - (60:1,27 [3] ImplicitExpression.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.mappings.txt
new file mode 100644
index 0000000000..8593cab083
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_DesignTime.mappings.txt
@@ -0,0 +1,19 @@
+Source Location: (1:0,1 [36] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml)
+|for(int i = 1; i <= 10; i++) {
+ |
+Generated Location: (736:18,1 [36] )
+|for(int i = 1; i <= 10; i++) {
+ |
+
+Source Location: (55:1,22 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml)
+|i|
+Generated Location: (921:24,22 [1] )
+|i|
+
+Source Location: (60:1,27 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml)
+|
+}|
+Generated Location: (1077:29,27 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.codegen.cs
new file mode 100644
index 0000000000..6a4191069a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.codegen.cs
@@ -0,0 +1,35 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "68460c577f1cb90794f25535a35a82ff2aa4c193"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"68460c577f1cb90794f25535a35a82ff2aa4c193", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+ for(int i = 1; i <= 10; i++) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>This is item #");
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.ir.txt
new file mode 100644
index 0000000000..c3d0aaab02
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ImplicitExpression_Runtime.ir.txt
@@ -0,0 +1,19 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ImplicitExpression_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [32] ImplicitExpression.cshtml)
+ IntermediateToken - (1:0,1 [32] ImplicitExpression.cshtml) - CSharp - for(int i = 1; i <= 10; i++) {\n
+ HtmlContent - (33:1,0 [21] ImplicitExpression.cshtml)
+ IntermediateToken - (33:1,0 [4] ImplicitExpression.cshtml) - Html -
+ IntermediateToken - (37:1,4 [3] ImplicitExpression.cshtml) - Html - <p>
+ IntermediateToken - (40:1,7 [14] ImplicitExpression.cshtml) - Html - This is item #
+ CSharpExpression - (55:1,22 [1] ImplicitExpression.cshtml)
+ IntermediateToken - (55:1,22 [1] ImplicitExpression.cshtml) - CSharp - i
+ HtmlContent - (56:1,23 [6] ImplicitExpression.cshtml)
+ IntermediateToken - (56:1,23 [4] ImplicitExpression.cshtml) - Html - </p>
+ IntermediateToken - (60:1,27 [2] ImplicitExpression.cshtml) - Html - \n
+ CSharpCode - (62:2,0 [1] ImplicitExpression.cshtml)
+ IntermediateToken - (62:2,0 [1] ImplicitExpression.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml
new file mode 100644
index 0000000000..3b56f0b173
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml
@@ -0,0 +1,25 @@
+@* These test files validate that end-to-end, incomplete directives don't throw. *@
+
+@addTagHelper
+@addTagHelper
+@addTagHelper "
+
+@removeTagHelper
+@removeTagHelper
+@removeTagHelper "
+
+@tagHelperPrefix
+@tagHelperPrefix
+@tagHelperPrefix "
+
+@inherits
+@inherits
+
+@functions
+@functions
+
+@section
+@section
+
+@section {
+@functions { \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs
new file mode 100644
index 0000000000..03f5c03321
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.codegen.cs
@@ -0,0 +1,70 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = ";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = ";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = ";
+ }
+ ))();
+ ((System.Action)(() => {
+ }
+ ))();
+ ((System.Action)(() => {
+ }
+ ))();
+ ((System.Action)(() => {
+ }
+ ))();
+ ((System.Action)(() => {
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..b01ced2ed2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.diagnostics.txt
@@ -0,0 +1,27 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,2): Error RZ1018: Directive 'addTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,14): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,2): Error RZ1018: Directive 'addTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,15): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,15): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,15): Error RZ1020: Invalid tag helper directive look up text '"'. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,2): Error RZ1018: Directive 'removeTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,17): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,2): Error RZ1018: Directive 'removeTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,18): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(9,18): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(9,18): Error RZ1020: Invalid tag helper directive look up text '"'. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,2): Error RZ1018: Directive 'tagHelperPrefix' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,2): Error RZ1018: Directive 'tagHelperPrefix' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,1): Error RZ2001: The 'tagHelperPrefix' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,18): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,1): Error RZ2001: The 'tagHelperPrefix' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,18): Error RZ1020: Invalid tag helper directive 'tagHelperPrefix' value. '"' is not allowed in prefix '"'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,10): Error RZ1013: The 'inherits' directive expects a type name.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(16,1): Error RZ2001: The 'inherits' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(16,11): Error RZ1013: The 'inherits' directive expects a type name.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(19,1): Error RZ1017: Unexpected literal following the 'functions' directive. Expected '{'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(21,1): Error RZ1017: Unexpected literal following the 'functions' directive. Expected '{'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(21,9): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(22,10): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(24,10): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(25,12): Error RZ1006: The functions block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt
new file mode 100644
index 0000000000..f21273aeb2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.ir.txt
@@ -0,0 +1,84 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (100:2,13 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (116:3,14 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (132:4,14 [1] IncompleteDirectives.cshtml) - "
+ DirectiveToken - (153:6,16 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (172:7,17 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (191:8,17 [1] IncompleteDirectives.cshtml) - "
+ DirectiveToken - (212:10,16 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (231:11,17 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (250:12,17 [1] IncompleteDirectives.cshtml) - "
+ DirectiveToken - (264:14,9 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (276:15,10 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (315:20,8 [0] IncompleteDirectives.cshtml) -
+ DirectiveToken - (326:21,9 [0] IncompleteDirectives.cshtml) -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (100:2,13 [0] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (100:2,13 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (100:2,13 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (100:2,13 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (116:3,14 [0] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (116:3,14 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (116:3,14 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (116:3,14 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (132:4,14 [1] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (132:4,14 [1] IncompleteDirectives.cshtml) - "
+ HtmlContent - (133:4,15 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (133:4,15 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (153:6,16 [0] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (153:6,16 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (153:6,16 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (153:6,16 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (172:7,17 [0] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (172:7,17 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (172:7,17 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (172:7,17 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (191:8,17 [1] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (191:8,17 [1] IncompleteDirectives.cshtml) - "
+ HtmlContent - (192:8,18 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (192:8,18 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (212:10,16 [0] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (212:10,16 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (212:10,16 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (212:10,16 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (231:11,17 [0] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (231:11,17 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (231:11,17 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (231:11,17 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (250:12,17 [1] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (250:12,17 [1] IncompleteDirectives.cshtml) - "
+ HtmlContent - (251:12,18 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (251:12,18 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (255:14,0 [9] IncompleteDirectives.cshtml) - inherits
+ DirectiveToken - (264:14,9 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (264:14,9 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (264:14,9 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (266:15,0 [10] IncompleteDirectives.cshtml) - inherits
+ DirectiveToken - (276:15,10 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (276:15,10 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (276:15,10 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (280:17,0 [12] IncompleteDirectives.cshtml) - functions
+ MalformedDirective - (292:18,0 [15] IncompleteDirectives.cshtml) - functions
+ MalformedDirective - (307:20,0 [8] IncompleteDirectives.cshtml) - section
+ DirectiveToken - (315:20,8 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (315:20,8 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (315:20,8 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (317:21,0 [9] IncompleteDirectives.cshtml) - section
+ DirectiveToken - (326:21,9 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (326:21,9 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (326:21,9 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (330:23,0 [9] IncompleteDirectives.cshtml) - section
+ HtmlContent - (339:23,9 [3] IncompleteDirectives.cshtml)
+ IntermediateToken - (339:23,9 [3] IncompleteDirectives.cshtml) - Html - {\n
+ MalformedDirective - (342:24,0 [12] IncompleteDirectives.cshtml) - functions
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt
new file mode 100644
index 0000000000..b5f9ac8df5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_DesignTime.mappings.txt
@@ -0,0 +1,65 @@
+Source Location: (100:2,13 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (427:10,38 [0] )
+||
+
+Source Location: (116:3,14 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (529:14,38 [0] )
+||
+
+Source Location: (132:4,14 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+|"|
+Generated Location: (630:18,37 [1] )
+|"|
+
+Source Location: (153:6,16 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (732:22,38 [0] )
+||
+
+Source Location: (172:7,17 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (834:26,38 [0] )
+||
+
+Source Location: (191:8,17 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+|"|
+Generated Location: (935:30,37 [1] )
+|"|
+
+Source Location: (212:10,16 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1037:34,38 [0] )
+||
+
+Source Location: (231:11,17 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1139:38,38 [0] )
+||
+
+Source Location: (250:12,17 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+|"|
+Generated Location: (1240:42,37 [1] )
+|"|
+
+Source Location: (264:14,9 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1304:46,0 [0] )
+||
+
+Source Location: (276:15,10 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1357:49,0 [0] )
+||
+
+Source Location: (315:20,8 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1410:52,0 [0] )
+||
+
+Source Location: (326:21,9 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml)
+||
+Generated Location: (1463:55,0 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs
new file mode 100644
index 0000000000..fd04cb19d2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.codegen.cs
@@ -0,0 +1,27 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "41721dbbbcb64df19057144a2095a3e1f7466401"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"41721dbbbcb64df19057144a2095a3e1f7466401", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n\r\n");
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n\r\n");
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n\r\n");
+ WriteLiteral("{\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..b01ced2ed2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.diagnostics.txt
@@ -0,0 +1,27 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,2): Error RZ1018: Directive 'addTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(3,14): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,2): Error RZ1018: Directive 'addTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(4,15): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,15): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(5,15): Error RZ1020: Invalid tag helper directive look up text '"'. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,2): Error RZ1018: Directive 'removeTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(7,17): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,2): Error RZ1018: Directive 'removeTagHelper' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(8,18): Error RZ1020: Invalid tag helper directive look up text ''. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(9,18): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(9,18): Error RZ1020: Invalid tag helper directive look up text '"'. The correct look up text format is: "name, assemblyName".
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(11,2): Error RZ1018: Directive 'tagHelperPrefix' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,2): Error RZ1018: Directive 'tagHelperPrefix' must have a value.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(12,1): Error RZ2001: The 'tagHelperPrefix' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,18): Error RZ1000: Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,1): Error RZ2001: The 'tagHelperPrefix' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(13,18): Error RZ1020: Invalid tag helper directive 'tagHelperPrefix' value. '"' is not allowed in prefix '"'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(15,10): Error RZ1013: The 'inherits' directive expects a type name.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(16,1): Error RZ2001: The 'inherits' directive may only occur once per document.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(16,11): Error RZ1013: The 'inherits' directive expects a type name.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(19,1): Error RZ1017: Unexpected literal following the 'functions' directive. Expected '{'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(21,1): Error RZ1017: Unexpected literal following the 'functions' directive. Expected '{'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(21,9): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(22,10): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(24,10): Error RZ1015: The 'section' directive expects an identifier.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives.cshtml(25,12): Error RZ1006: The functions block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt
new file mode 100644
index 0000000000..ecffead8c5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteDirectives_Runtime.ir.txt
@@ -0,0 +1,54 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteDirectives_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (83:0,83 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (83:0,83 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (100:2,13 [2] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (100:2,13 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (116:3,14 [2] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (116:3,14 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (132:4,14 [3] IncompleteDirectives.cshtml) - addTagHelper
+ DirectiveToken - (132:4,14 [3] IncompleteDirectives.cshtml) - "
+ HtmlContent - (135:5,0 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (135:5,0 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (153:6,16 [2] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (153:6,16 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (172:7,17 [2] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (172:7,17 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (191:8,17 [3] IncompleteDirectives.cshtml) - removeTagHelper
+ DirectiveToken - (191:8,17 [3] IncompleteDirectives.cshtml) - "
+ HtmlContent - (194:9,0 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (194:9,0 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (212:10,16 [2] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (212:10,16 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (231:11,17 [2] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (231:11,17 [2] IncompleteDirectives.cshtml) -
+ MalformedDirective - (250:12,17 [3] IncompleteDirectives.cshtml) - tagHelperPrefix
+ DirectiveToken - (250:12,17 [3] IncompleteDirectives.cshtml) - "
+ HtmlContent - (253:13,0 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (253:13,0 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (255:14,0 [9] IncompleteDirectives.cshtml) - inherits
+ DirectiveToken - (264:14,9 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (264:14,9 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (264:14,9 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (266:15,0 [10] IncompleteDirectives.cshtml) - inherits
+ DirectiveToken - (276:15,10 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (276:15,10 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (276:15,10 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (280:17,0 [12] IncompleteDirectives.cshtml) - functions
+ MalformedDirective - (292:18,0 [15] IncompleteDirectives.cshtml) - functions
+ MalformedDirective - (307:20,0 [8] IncompleteDirectives.cshtml) - section
+ DirectiveToken - (315:20,8 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (315:20,8 [2] IncompleteDirectives.cshtml)
+ IntermediateToken - (315:20,8 [2] IncompleteDirectives.cshtml) - Html - \n
+ MalformedDirective - (317:21,0 [9] IncompleteDirectives.cshtml) - section
+ DirectiveToken - (326:21,9 [0] IncompleteDirectives.cshtml) -
+ HtmlContent - (326:21,9 [4] IncompleteDirectives.cshtml)
+ IntermediateToken - (326:21,9 [4] IncompleteDirectives.cshtml) - Html - \n\n
+ MalformedDirective - (330:23,0 [9] IncompleteDirectives.cshtml) - section
+ HtmlContent - (339:23,9 [3] IncompleteDirectives.cshtml)
+ IntermediateToken - (339:23,9 [3] IncompleteDirectives.cshtml) - Html - {\n
+ MalformedDirective - (342:24,0 [12] IncompleteDirectives.cshtml) - functions
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml
new file mode 100644
index 0000000000..022784f426
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml
@@ -0,0 +1,3 @@
+@addTagHelper "*, TestAssembly"
+
+<p class=" \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.codegen.cs
new file mode 100644
index 0000000000..3a01486099
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.codegen.cs
@@ -0,0 +1,28 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..10a2d590e2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml(3,2): Error RZ1035: Missing close angle for tag helper 'p'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml(3,2): Error RZ1034: Found a malformed 'p' tag helper. Tag helpers must have a start and end tag or be self closing.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.ir.txt
new file mode 100644
index 0000000000..81a7de97d8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] IncompleteTagHelper.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] IncompleteTagHelper.cshtml)
+ IntermediateToken - (31:0,31 [4] IncompleteTagHelper.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [10] IncompleteTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (45:2,10 [0] IncompleteTagHelper.cshtml)
+ IntermediateToken - (45:2,10 [0] IncompleteTagHelper.cshtml) - Html -
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.mappings.txt
new file mode 100644
index 0000000000..cad8cf7ea6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml)
+|"*, TestAssembly"|
+Generated Location: (503:11,37 [17] )
+|"*, TestAssembly"|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.codegen.cs
new file mode 100644
index 0000000000..ed5360e018
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.codegen.cs
@@ -0,0 +1,52 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "976899f0b1218a2ad5755b5bee8aa5f9b27068b6"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"976899f0b1218a2ad5755b5bee8aa5f9b27068b6", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString(""), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..10a2d590e2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml(3,2): Error RZ1035: Missing close angle for tag helper 'p'.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper.cshtml(3,2): Error RZ1034: Found a malformed 'p' tag helper. Tag helpers must have a start and end tag or be self closing.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.ir.txt
new file mode 100644
index 0000000000..dfc5fa13b1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/IncompleteTagHelper_Runtime.ir.txt
@@ -0,0 +1,16 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_IncompleteTagHelper_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] IncompleteTagHelper.cshtml)
+ IntermediateToken - (33:1,0 [2] IncompleteTagHelper.cshtml) - Html - \n
+ TagHelper - (35:2,0 [10] IncompleteTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml
new file mode 100644
index 0000000000..cf92e3466b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml
@@ -0,0 +1,3 @@
+@inherits foo.bar<baz<biz>>.boz
+
+@foo() \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.codegen.cs
new file mode 100644
index 0000000000..bb73db8e52
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.codegen.cs
@@ -0,0 +1,31 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_DesignTime : foo.bar<baz<biz>>.boz
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+foo.bar<baz<biz>>.boz __typeHelper = default(foo.bar<baz<biz>>.boz);
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml"
+__o = foo();
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.ir.txt
new file mode 100644
index 0000000000..5d070ecece
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.ir.txt
@@ -0,0 +1,16 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_DesignTime - foo.bar<baz<biz>>.boz -
+ DesignTimeDirective -
+ DirectiveToken - (10:0,10 [21] Inherits.cshtml) - foo.bar<baz<biz>>.boz
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] Inherits.cshtml)
+ IntermediateToken - (33:1,0 [2] Inherits.cshtml) - Html - \n
+ CSharpExpression - (36:2,1 [5] Inherits.cshtml)
+ IntermediateToken - (36:2,1 [5] Inherits.cshtml) - CSharp - foo()
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.mappings.txt
new file mode 100644
index 0000000000..bbde1e3ca1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (10:0,10 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml)
+|foo.bar<baz<biz>>.boz|
+Generated Location: (401:10,0 [21] )
+|foo.bar<baz<biz>>.boz|
+
+Source Location: (36:2,1 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml)
+|foo()|
+Generated Location: (875:22,6 [5] )
+|foo()|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.codegen.cs
new file mode 100644
index 0000000000..5ca5961c65
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.codegen.cs
@@ -0,0 +1,24 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0f131d73e4e22423fc85cc3e091dd106da637d92"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"0f131d73e4e22423fc85cc3e091dd106da637d92", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_Runtime : foo.bar<baz<biz>>.boz
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits.cshtml"
+Write(foo());
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.ir.txt
new file mode 100644
index 0000000000..e901fffac8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Inherits_Runtime.ir.txt
@@ -0,0 +1,10 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Inherits_Runtime - foo.bar<baz<biz>>.boz -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] Inherits.cshtml)
+ IntermediateToken - (33:1,0 [2] Inherits.cshtml) - Html - \n
+ CSharpExpression - (36:2,1 [5] Inherits.cshtml)
+ IntermediateToken - (36:2,1 [5] Inherits.cshtml) - CSharp - foo()
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml
new file mode 100644
index 0000000000..2a4ba7216f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml
@@ -0,0 +1,3 @@
+@section Link(string link) {
+ <a href="@if(link != null) { @link } else { <text>#</text> }" />
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.codegen.cs
new file mode 100644
index 0000000000..0dac7a2c04
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.codegen.cs
@@ -0,0 +1,46 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object Link = null;
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ if(link != null) {
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ __o = link;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ } else {
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..66af9b7600
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml(1,14): Error RZ1017: Unexpected literal following the 'section' directive. Expected '{'.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.ir.txt
new file mode 100644
index 0000000000..76c1d91a0c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.ir.txt
@@ -0,0 +1,29 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (9:0,9 [4] InlineBlocks.cshtml) - Link
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ MalformedDirective - (0:0,0 [13] InlineBlocks.cshtml) - section
+ DirectiveToken - (9:0,9 [4] InlineBlocks.cshtml) - Link
+ HtmlContent - (13:0,13 [23] InlineBlocks.cshtml)
+ IntermediateToken - (13:0,13 [21] InlineBlocks.cshtml) - Html - (string link) {\n
+ IntermediateToken - (34:1,4 [2] InlineBlocks.cshtml) - Html - <a
+ HtmlAttribute - (36:1,6 [59] InlineBlocks.cshtml) - href=" - "
+ CSharpCodeAttributeValue - (43:1,13 [51] InlineBlocks.cshtml) -
+ IntermediateToken - (44:1,14 [19] InlineBlocks.cshtml) - CSharp - if(link != null) {
+ CSharpExpression - (64:1,34 [4] InlineBlocks.cshtml)
+ IntermediateToken - (64:1,34 [4] InlineBlocks.cshtml) - CSharp - link
+ IntermediateToken - (68:1,38 [10] InlineBlocks.cshtml) - CSharp - } else {
+ HtmlContent - (84:1,54 [1] InlineBlocks.cshtml)
+ IntermediateToken - (84:1,54 [1] InlineBlocks.cshtml) - Html - #
+ IntermediateToken - (92:1,62 [2] InlineBlocks.cshtml) - CSharp - }
+ HtmlContent - (95:1,65 [6] InlineBlocks.cshtml)
+ IntermediateToken - (95:1,65 [3] InlineBlocks.cshtml) - Html - />
+ IntermediateToken - (98:1,68 [3] InlineBlocks.cshtml) - Html - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.mappings.txt
new file mode 100644
index 0000000000..defa39bbc4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_DesignTime.mappings.txt
@@ -0,0 +1,25 @@
+Source Location: (9:0,9 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml)
+|Link|
+Generated Location: (403:10,22 [4] )
+|Link|
+
+Source Location: (44:1,14 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml)
+|if(link != null) { |
+Generated Location: (833:22,14 [19] )
+|if(link != null) { |
+
+Source Location: (64:1,34 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml)
+|link|
+Generated Location: (1007:27,34 [4] )
+|link|
+
+Source Location: (68:1,38 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml)
+| } else { |
+Generated Location: (1171:32,38 [10] )
+| } else { |
+
+Source Location: (92:1,62 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml)
+| }|
+Generated Location: (1364:37,62 [2] )
+| }|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.codegen.cs
new file mode 100644
index 0000000000..e588d26d67
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.codegen.cs
@@ -0,0 +1,48 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e7fa74a13b1e78fed87942ccd83aa733810e8664"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"e7fa74a13b1e78fed87942ccd83aa733810e8664", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("(string link) {\r\n <a");
+ BeginWriteAttribute("href", " href=\"", 36, "\"", 94, 1);
+ WriteAttributeValue("", 43, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ if(link != null) {
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ Write(link);
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ } else {
+
+#line default
+#line hidden
+ WriteLiteral("#");
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml"
+ }
+
+#line default
+#line hidden
+ PopWriter();
+ }
+ ), 43, 51, false);
+ EndWriteAttribute();
+ WriteLiteral(" />\r\n}");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..66af9b7600
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks.cshtml(1,14): Error RZ1017: Unexpected literal following the 'section' directive. Expected '{'.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.ir.txt
new file mode 100644
index 0000000000..eb8fd5d9f6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InlineBlocks_Runtime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InlineBlocks_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ MalformedDirective - (0:0,0 [13] InlineBlocks.cshtml) - section
+ DirectiveToken - (9:0,9 [4] InlineBlocks.cshtml) - Link
+ HtmlContent - (13:0,13 [23] InlineBlocks.cshtml)
+ IntermediateToken - (13:0,13 [21] InlineBlocks.cshtml) - Html - (string link) {\n
+ IntermediateToken - (34:1,4 [2] InlineBlocks.cshtml) - Html - <a
+ HtmlAttribute - (36:1,6 [59] InlineBlocks.cshtml) - href=" - "
+ CSharpCodeAttributeValue - (43:1,13 [51] InlineBlocks.cshtml) -
+ IntermediateToken - (44:1,14 [19] InlineBlocks.cshtml) - CSharp - if(link != null) {
+ CSharpExpression - (64:1,34 [4] InlineBlocks.cshtml)
+ IntermediateToken - (64:1,34 [4] InlineBlocks.cshtml) - CSharp - link
+ IntermediateToken - (68:1,38 [10] InlineBlocks.cshtml) - CSharp - } else {
+ HtmlContent - (84:1,54 [1] InlineBlocks.cshtml)
+ IntermediateToken - (84:1,54 [1] InlineBlocks.cshtml) - Html - #
+ IntermediateToken - (92:1,62 [2] InlineBlocks.cshtml) - CSharp - }
+ HtmlContent - (95:1,65 [6] InlineBlocks.cshtml)
+ IntermediateToken - (95:1,65 [3] InlineBlocks.cshtml) - Html - />
+ IntermediateToken - (98:1,68 [3] InlineBlocks.cshtml) - Html - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml
new file mode 100644
index 0000000000..bd273c57e1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml
@@ -0,0 +1,38 @@
+@{
+ int i = 1;
+ var foo = @<p>Bar</p>;
+ @:Hello, World
+ <p>Hello, World</p>
+}
+
+@while(i <= 10) {
+ <p>Hello from C#, #@(i)</p>
+ i += 1;
+}
+
+@if(i == 11) {
+ <p>We wrote 10 lines!</p>
+}
+
+@switch(i) {
+ case 11:
+ <p>No really, we wrote 10 lines!</p>
+ break;
+ default:
+ <p>Actually, we didn't...</p>
+ break;
+}
+
+@for(int j = 1; j <= 10; j += 2) {
+ <p>Hello again from C#, #@(j)</p>
+}
+
+@try {
+ <p>That time, we wrote 5 lines!</p>
+} catch(Exception ex) {
+ <p>Oh no! An error occurred: @(ex.Message)</p>
+}
+
+@lock(new object()) {
+ <p>This block is locked, for your security!</p>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.codegen.cs
new file mode 100644
index 0000000000..04f1daad49
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.codegen.cs
@@ -0,0 +1,146 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+ int i = 1;
+ var foo =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ }
+ )
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ ;
+
+
+#line default
+#line hidden
+
+
+
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ while(i <= 10) {
+
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+ i += 1;
+}
+
+#line default
+#line hidden
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ if(i == 11) {
+
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ switch(i) {
+ case 11:
+
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+ break;
+ default:
+
+
+#line default
+#line hidden
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+ break;
+}
+
+#line default
+#line hidden
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+
+#line default
+#line hidden
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ __o = j;
+
+#line default
+#line hidden
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ try {
+
+
+#line default
+#line hidden
+#line 31 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+} catch(Exception ex) {
+
+
+#line default
+#line hidden
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ __o = ex.Message;
+
+#line default
+#line hidden
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ lock(new object()) {
+
+
+#line default
+#line hidden
+#line 37 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.ir.txt
new file mode 100644
index 0000000000..59e7be3397
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.ir.txt
@@ -0,0 +1,111 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [32] Instrumented.cshtml)
+ IntermediateToken - (2:0,2 [32] Instrumented.cshtml) - CSharp - \n int i = 1;\n var foo =
+ Template - (35:2,15 [10] Instrumented.cshtml)
+ HtmlContent - (35:2,15 [10] Instrumented.cshtml)
+ IntermediateToken - (35:2,15 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (38:2,18 [3] Instrumented.cshtml) - Html - Bar
+ IntermediateToken - (41:2,21 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (45:2,25 [7] Instrumented.cshtml)
+ IntermediateToken - (45:2,25 [7] Instrumented.cshtml) - CSharp - ;\n
+ HtmlContent - (54:3,6 [14] Instrumented.cshtml)
+ IntermediateToken - (54:3,6 [14] Instrumented.cshtml) - Html - Hello, World\n
+ CSharpCode - (68:4,0 [4] Instrumented.cshtml)
+ IntermediateToken - (68:4,0 [4] Instrumented.cshtml) - CSharp -
+ HtmlContent - (72:4,4 [19] Instrumented.cshtml)
+ IntermediateToken - (72:4,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (75:4,7 [12] Instrumented.cshtml) - Html - Hello, World
+ IntermediateToken - (87:4,19 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (91:4,23 [2] Instrumented.cshtml)
+ IntermediateToken - (91:4,23 [2] Instrumented.cshtml) - CSharp - \n
+ HtmlContent - (96:6,0 [2] Instrumented.cshtml)
+ IntermediateToken - (96:6,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (99:7,1 [22] Instrumented.cshtml)
+ IntermediateToken - (99:7,1 [22] Instrumented.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (121:8,4 [19] Instrumented.cshtml)
+ IntermediateToken - (121:8,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (124:8,7 [16] Instrumented.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (142:8,25 [1] Instrumented.cshtml)
+ IntermediateToken - (142:8,25 [1] Instrumented.cshtml) - CSharp - i
+ HtmlContent - (144:8,27 [4] Instrumented.cshtml)
+ IntermediateToken - (144:8,27 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (148:8,31 [16] Instrumented.cshtml)
+ IntermediateToken - (148:8,31 [16] Instrumented.cshtml) - CSharp - \n i += 1;\n}
+ HtmlContent - (164:10,1 [4] Instrumented.cshtml)
+ IntermediateToken - (164:10,1 [4] Instrumented.cshtml) - Html - \n\n
+ CSharpCode - (169:12,1 [19] Instrumented.cshtml)
+ IntermediateToken - (169:12,1 [19] Instrumented.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (188:13,4 [25] Instrumented.cshtml)
+ IntermediateToken - (188:13,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (191:13,7 [18] Instrumented.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (209:13,25 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (213:13,29 [3] Instrumented.cshtml)
+ IntermediateToken - (213:13,29 [3] Instrumented.cshtml) - CSharp - \n}
+ HtmlContent - (216:14,1 [4] Instrumented.cshtml)
+ IntermediateToken - (216:14,1 [4] Instrumented.cshtml) - Html - \n\n
+ CSharpCode - (221:16,1 [35] Instrumented.cshtml)
+ IntermediateToken - (221:16,1 [35] Instrumented.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (256:18,8 [36] Instrumented.cshtml)
+ IntermediateToken - (256:18,8 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (259:18,11 [29] Instrumented.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (288:18,40 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (292:18,44 [40] Instrumented.cshtml)
+ IntermediateToken - (292:18,44 [40] Instrumented.cshtml) - CSharp - \n break;\n default:\n
+ HtmlContent - (332:21,8 [29] Instrumented.cshtml)
+ IntermediateToken - (332:21,8 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (335:21,11 [22] Instrumented.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (357:21,33 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (361:21,37 [19] Instrumented.cshtml)
+ IntermediateToken - (361:21,37 [19] Instrumented.cshtml) - CSharp - \n break;\n}
+ HtmlContent - (380:23,1 [4] Instrumented.cshtml)
+ IntermediateToken - (380:23,1 [4] Instrumented.cshtml) - Html - \n\n
+ CSharpCode - (385:25,1 [39] Instrumented.cshtml)
+ IntermediateToken - (385:25,1 [39] Instrumented.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (424:26,4 [25] Instrumented.cshtml)
+ IntermediateToken - (424:26,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (427:26,7 [22] Instrumented.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (451:26,31 [1] Instrumented.cshtml)
+ IntermediateToken - (451:26,31 [1] Instrumented.cshtml) - CSharp - j
+ HtmlContent - (453:26,33 [4] Instrumented.cshtml)
+ IntermediateToken - (453:26,33 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (457:26,37 [3] Instrumented.cshtml)
+ IntermediateToken - (457:26,37 [3] Instrumented.cshtml) - CSharp - \n}
+ HtmlContent - (460:27,1 [4] Instrumented.cshtml)
+ IntermediateToken - (460:27,1 [4] Instrumented.cshtml) - Html - \n\n
+ CSharpCode - (465:29,1 [11] Instrumented.cshtml)
+ IntermediateToken - (465:29,1 [11] Instrumented.cshtml) - CSharp - try {\n
+ HtmlContent - (476:30,4 [35] Instrumented.cshtml)
+ IntermediateToken - (476:30,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (479:30,7 [28] Instrumented.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (507:30,35 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (511:30,39 [31] Instrumented.cshtml)
+ IntermediateToken - (511:30,39 [31] Instrumented.cshtml) - CSharp - \n} catch(Exception ex) {\n
+ HtmlContent - (542:32,4 [29] Instrumented.cshtml)
+ IntermediateToken - (542:32,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (545:32,7 [26] Instrumented.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (573:32,35 [10] Instrumented.cshtml)
+ IntermediateToken - (573:32,35 [10] Instrumented.cshtml) - CSharp - ex.Message
+ HtmlContent - (584:32,46 [4] Instrumented.cshtml)
+ IntermediateToken - (584:32,46 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (588:32,50 [3] Instrumented.cshtml)
+ IntermediateToken - (588:32,50 [3] Instrumented.cshtml) - CSharp - \n}
+ HtmlContent - (591:33,1 [4] Instrumented.cshtml)
+ IntermediateToken - (591:33,1 [4] Instrumented.cshtml) - Html - \n\n
+ CSharpCode - (596:35,1 [26] Instrumented.cshtml)
+ IntermediateToken - (596:35,1 [26] Instrumented.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (622:36,4 [47] Instrumented.cshtml)
+ IntermediateToken - (622:36,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (625:36,7 [40] Instrumented.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (665:36,47 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (669:36,51 [3] Instrumented.cshtml)
+ IntermediateToken - (669:36,51 [3] Instrumented.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.mappings.txt
new file mode 100644
index 0000000000..4165c88fa9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_DesignTime.mappings.txt
@@ -0,0 +1,153 @@
+Source Location: (2:0,2 [32] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+ int i = 1;
+ var foo = |
+Generated Location: (725:18,2 [32] )
+|
+ int i = 1;
+ var foo = |
+
+Source Location: (45:2,25 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|;
+ |
+Generated Location: (1003:28,25 [7] )
+|;
+ |
+
+Source Location: (68:4,0 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+| |
+Generated Location: (1043:33,0 [4] )
+| |
+
+Source Location: (91:4,23 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+|
+Generated Location: (1096:34,35 [2] )
+|
+|
+
+Source Location: (99:7,1 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|while(i <= 10) {
+ |
+Generated Location: (1189:37,1 [22] )
+|while(i <= 10) {
+ |
+
+Source Location: (142:8,25 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|i|
+Generated Location: (1357:43,25 [1] )
+|i|
+
+Source Location: (148:8,31 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+ i += 1;
+}|
+Generated Location: (1511:48,31 [16] )
+|
+ i += 1;
+}|
+
+Source Location: (169:12,1 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|if(i == 11) {
+ |
+Generated Location: (1650:55,1 [19] )
+|if(i == 11) {
+ |
+
+Source Location: (213:13,29 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+}|
+Generated Location: (1820:61,29 [3] )
+|
+}|
+
+Source Location: (221:16,1 [35] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|switch(i) {
+ case 11:
+ |
+Generated Location: (1946:67,1 [35] )
+|switch(i) {
+ case 11:
+ |
+
+Source Location: (292:18,44 [40] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+ break;
+ default:
+ |
+Generated Location: (2147:74,44 [40] )
+|
+ break;
+ default:
+ |
+
+Source Location: (361:21,37 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+ break;
+}|
+Generated Location: (2346:82,37 [19] )
+|
+ break;
+}|
+
+Source Location: (385:25,1 [39] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|for(int j = 1; j <= 10; j += 2) {
+ |
+Generated Location: (2488:89,1 [39] )
+|for(int j = 1; j <= 10; j += 2) {
+ |
+
+Source Location: (451:26,31 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|j|
+Generated Location: (2680:95,31 [1] )
+|j|
+
+Source Location: (457:26,37 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+}|
+Generated Location: (2841:100,37 [3] )
+|
+}|
+
+Source Location: (465:29,1 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|try {
+ |
+Generated Location: (2967:106,1 [11] )
+|try {
+ |
+
+Source Location: (511:30,39 [31] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+} catch(Exception ex) {
+ |
+Generated Location: (3139:112,39 [31] )
+|
+} catch(Exception ex) {
+ |
+
+Source Location: (573:32,35 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|ex.Message|
+Generated Location: (3327:119,35 [10] )
+|ex.Message|
+
+Source Location: (588:32,50 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+}|
+Generated Location: (3510:124,50 [3] )
+|
+}|
+
+Source Location: (596:35,1 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|lock(new object()) {
+ |
+Generated Location: (3636:130,1 [26] )
+|lock(new object()) {
+ |
+
+Source Location: (669:36,51 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml)
+|
+}|
+Generated Location: (3835:136,51 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.codegen.cs
new file mode 100644
index 0000000000..9b7421b0de
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.codegen.cs
@@ -0,0 +1,144 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "3d0d9c94b62eeccf0a2a106b257a1ea1e22412a9"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"3d0d9c94b62eeccf0a2a106b257a1ea1e22412a9", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+
+ int i = 1;
+ var foo =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("<p>Bar</p>");
+ PopWriter();
+ }
+ )
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ ;
+
+#line default
+#line hidden
+ WriteLiteral(" ");
+ WriteLiteral("Hello, World\r\n <p>Hello, World</p>\r\n");
+ WriteLiteral("\r\n");
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ while(i <= 10) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello from C#, #");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ i += 1;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ if(i == 11) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>We wrote 10 lines!</p>\r\n");
+#line 15 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ switch(i) {
+ case 11:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>No really, we wrote 10 lines!</p>\r\n");
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ break;
+ default:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Actually, we didn\'t...</p>\r\n");
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ break;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello again from C#, #");
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ Write(j);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 28 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ try {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>That time, we wrote 5 lines!</p>\r\n");
+#line 32 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+} catch(Exception ex) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Oh no! An error occurred: ");
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ Write(ex.Message);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 34 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+ lock(new object()) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>This block is locked, for your security!</p>\r\n");
+#line 38 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.ir.txt
new file mode 100644
index 0000000000..2fb8fdbe9b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Instrumented_Runtime.ir.txt
@@ -0,0 +1,123 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Instrumented_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [32] Instrumented.cshtml)
+ IntermediateToken - (2:0,2 [32] Instrumented.cshtml) - CSharp - \n int i = 1;\n var foo =
+ Template - (35:2,15 [10] Instrumented.cshtml)
+ HtmlContent - (35:2,15 [10] Instrumented.cshtml)
+ IntermediateToken - (35:2,15 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (38:2,18 [3] Instrumented.cshtml) - Html - Bar
+ IntermediateToken - (41:2,21 [4] Instrumented.cshtml) - Html - </p>
+ CSharpCode - (45:2,25 [3] Instrumented.cshtml)
+ IntermediateToken - (45:2,25 [3] Instrumented.cshtml) - CSharp - ;\n
+ HtmlContent - (48:3,0 [4] Instrumented.cshtml)
+ IntermediateToken - (48:3,0 [4] Instrumented.cshtml) - Html -
+ HtmlContent - (54:3,6 [39] Instrumented.cshtml)
+ IntermediateToken - (54:3,6 [14] Instrumented.cshtml) - Html - Hello, World\n
+ IntermediateToken - (68:4,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (72:4,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (75:4,7 [12] Instrumented.cshtml) - Html - Hello, World
+ IntermediateToken - (87:4,19 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (91:4,23 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (93:5,0 [0] Instrumented.cshtml)
+ IntermediateToken - (93:5,0 [0] Instrumented.cshtml) - CSharp -
+ HtmlContent - (96:6,0 [2] Instrumented.cshtml)
+ IntermediateToken - (96:6,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (99:7,1 [18] Instrumented.cshtml)
+ IntermediateToken - (99:7,1 [18] Instrumented.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (117:8,0 [23] Instrumented.cshtml)
+ IntermediateToken - (117:8,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (121:8,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (124:8,7 [16] Instrumented.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (142:8,25 [1] Instrumented.cshtml)
+ IntermediateToken - (142:8,25 [1] Instrumented.cshtml) - CSharp - i
+ HtmlContent - (144:8,27 [6] Instrumented.cshtml)
+ IntermediateToken - (144:8,27 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (148:8,31 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (150:9,0 [16] Instrumented.cshtml)
+ IntermediateToken - (150:9,0 [16] Instrumented.cshtml) - CSharp - i += 1;\n}\n
+ HtmlContent - (166:11,0 [2] Instrumented.cshtml)
+ IntermediateToken - (166:11,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (169:12,1 [15] Instrumented.cshtml)
+ IntermediateToken - (169:12,1 [15] Instrumented.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (184:13,0 [31] Instrumented.cshtml)
+ IntermediateToken - (184:13,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (188:13,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (191:13,7 [18] Instrumented.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (209:13,25 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (213:13,29 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (215:14,0 [3] Instrumented.cshtml)
+ IntermediateToken - (215:14,0 [3] Instrumented.cshtml) - CSharp - }\n
+ HtmlContent - (218:15,0 [2] Instrumented.cshtml)
+ IntermediateToken - (218:15,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (221:16,1 [27] Instrumented.cshtml)
+ IntermediateToken - (221:16,1 [27] Instrumented.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (248:18,0 [46] Instrumented.cshtml)
+ IntermediateToken - (248:18,0 [8] Instrumented.cshtml) - Html -
+ IntermediateToken - (256:18,8 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (259:18,11 [29] Instrumented.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (288:18,40 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (292:18,44 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (294:19,0 [30] Instrumented.cshtml)
+ IntermediateToken - (294:19,0 [30] Instrumented.cshtml) - CSharp - break;\n default:\n
+ HtmlContent - (324:21,0 [39] Instrumented.cshtml)
+ IntermediateToken - (324:21,0 [8] Instrumented.cshtml) - Html -
+ IntermediateToken - (332:21,8 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (335:21,11 [22] Instrumented.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (357:21,33 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (361:21,37 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (363:22,0 [19] Instrumented.cshtml)
+ IntermediateToken - (363:22,0 [19] Instrumented.cshtml) - CSharp - break;\n}\n
+ HtmlContent - (382:24,0 [2] Instrumented.cshtml)
+ IntermediateToken - (382:24,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (385:25,1 [35] Instrumented.cshtml)
+ IntermediateToken - (385:25,1 [35] Instrumented.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (420:26,0 [29] Instrumented.cshtml)
+ IntermediateToken - (420:26,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (424:26,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (427:26,7 [22] Instrumented.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (451:26,31 [1] Instrumented.cshtml)
+ IntermediateToken - (451:26,31 [1] Instrumented.cshtml) - CSharp - j
+ HtmlContent - (453:26,33 [6] Instrumented.cshtml)
+ IntermediateToken - (453:26,33 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (457:26,37 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (459:27,0 [3] Instrumented.cshtml)
+ IntermediateToken - (459:27,0 [3] Instrumented.cshtml) - CSharp - }\n
+ HtmlContent - (462:28,0 [2] Instrumented.cshtml)
+ IntermediateToken - (462:28,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (465:29,1 [7] Instrumented.cshtml)
+ IntermediateToken - (465:29,1 [7] Instrumented.cshtml) - CSharp - try {\n
+ HtmlContent - (472:30,0 [41] Instrumented.cshtml)
+ IntermediateToken - (472:30,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (476:30,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (479:30,7 [28] Instrumented.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (507:30,35 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (511:30,39 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (513:31,0 [25] Instrumented.cshtml)
+ IntermediateToken - (513:31,0 [25] Instrumented.cshtml) - CSharp - } catch(Exception ex) {\n
+ HtmlContent - (538:32,0 [33] Instrumented.cshtml)
+ IntermediateToken - (538:32,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (542:32,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (545:32,7 [26] Instrumented.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (573:32,35 [10] Instrumented.cshtml)
+ IntermediateToken - (573:32,35 [10] Instrumented.cshtml) - CSharp - ex.Message
+ HtmlContent - (584:32,46 [6] Instrumented.cshtml)
+ IntermediateToken - (584:32,46 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (588:32,50 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (590:33,0 [3] Instrumented.cshtml)
+ IntermediateToken - (590:33,0 [3] Instrumented.cshtml) - CSharp - }\n
+ HtmlContent - (593:34,0 [2] Instrumented.cshtml)
+ IntermediateToken - (593:34,0 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (596:35,1 [22] Instrumented.cshtml)
+ IntermediateToken - (596:35,1 [22] Instrumented.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (618:36,0 [53] Instrumented.cshtml)
+ IntermediateToken - (618:36,0 [4] Instrumented.cshtml) - Html -
+ IntermediateToken - (622:36,4 [3] Instrumented.cshtml) - Html - <p>
+ IntermediateToken - (625:36,7 [40] Instrumented.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (665:36,47 [4] Instrumented.cshtml) - Html - </p>
+ IntermediateToken - (669:36,51 [2] Instrumented.cshtml) - Html - \n
+ CSharpCode - (671:37,0 [1] Instrumented.cshtml)
+ IntermediateToken - (671:37,0 [1] Instrumented.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml
new file mode 100644
index 0000000000..712ef42848
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml
@@ -0,0 +1,5 @@
+@{
+ for(int i = 1; i <= 10; i++) {
+ <p>Hello from C#, #@(i.ToString())</p>
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.codegen.cs
new file mode 100644
index 0000000000..e4c9a94c7d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.codegen.cs
@@ -0,0 +1,40 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+
+ for(int i = 1; i <= 10; i++) {
+
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+ __o = i.ToString();
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.ir.txt
new file mode 100644
index 0000000000..c3afcf0f54
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.ir.txt
@@ -0,0 +1,22 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [46] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (2:0,2 [46] MarkupInCodeBlock.cshtml) - CSharp - \n for(int i = 1; i <= 10; i++) {\n
+ HtmlContent - (48:2,8 [19] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (48:2,8 [3] MarkupInCodeBlock.cshtml) - Html - <p>
+ IntermediateToken - (51:2,11 [16] MarkupInCodeBlock.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:2,29 [12] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (69:2,29 [12] MarkupInCodeBlock.cshtml) - CSharp - i.ToString()
+ HtmlContent - (82:2,42 [4] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (82:2,42 [4] MarkupInCodeBlock.cshtml) - Html - </p>
+ CSharpCode - (86:2,46 [9] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (86:2,46 [9] MarkupInCodeBlock.cshtml) - CSharp - \n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.mappings.txt
new file mode 100644
index 0000000000..2abd44edf5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_DesignTime.mappings.txt
@@ -0,0 +1,23 @@
+Source Location: (2:0,2 [46] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml)
+|
+ for(int i = 1; i <= 10; i++) {
+ |
+Generated Location: (735:18,2 [46] )
+|
+ for(int i = 1; i <= 10; i++) {
+ |
+
+Source Location: (69:2,29 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml)
+|i.ToString()|
+Generated Location: (936:25,29 [12] )
+|i.ToString()|
+
+Source Location: (86:2,46 [9] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml)
+|
+ }
+|
+Generated Location: (1121:30,46 [9] )
+|
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.codegen.cs
new file mode 100644
index 0000000000..7a2b0aaf53
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.codegen.cs
@@ -0,0 +1,36 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "539d5763b7091d29df375085f623b9086e7f8ad6"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"539d5763b7091d29df375085f623b9086e7f8ad6", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+
+ for(int i = 1; i <= 10; i++) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello from C#, #");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+ Write(i.ToString());
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock.cshtml"
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.ir.txt
new file mode 100644
index 0000000000..a543cca51d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MarkupInCodeBlock_Runtime.ir.txt
@@ -0,0 +1,19 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MarkupInCodeBlock_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [38] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (2:0,2 [38] MarkupInCodeBlock.cshtml) - CSharp - \n for(int i = 1; i <= 10; i++) {\n
+ HtmlContent - (40:2,0 [27] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (40:2,0 [8] MarkupInCodeBlock.cshtml) - Html -
+ IntermediateToken - (48:2,8 [3] MarkupInCodeBlock.cshtml) - Html - <p>
+ IntermediateToken - (51:2,11 [16] MarkupInCodeBlock.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:2,29 [12] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (69:2,29 [12] MarkupInCodeBlock.cshtml) - CSharp - i.ToString()
+ HtmlContent - (82:2,42 [6] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (82:2,42 [4] MarkupInCodeBlock.cshtml) - Html - </p>
+ IntermediateToken - (86:2,46 [2] MarkupInCodeBlock.cshtml) - Html - \n
+ CSharpCode - (88:3,0 [7] MarkupInCodeBlock.cshtml)
+ IntermediateToken - (88:3,0 [7] MarkupInCodeBlock.cshtml) - CSharp - }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml
new file mode 100644
index 0000000000..c001d4945d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml
@@ -0,0 +1,20 @@
+@addTagHelper "*, TestAssembly"
+
+<p catchall-unbound-required>
+ <input nottaghelper />
+ <input class="btn"
+ catchall-unbound-required />
+ <input
+ class="btn" catchall-unbound-required input-unbound-required input-bound-required-string="hello" />
+ <input
+ class="btn"
+ catchall-unbound-required
+ input-unbound-required catchall-bound-string="world" input-bound-required-string="hello2" />
+ <input class="btn"
+ catchall-unbound-required="hello"
+ input-unbound-required="hello2"
+ catchall-unbound-required
+ input-bound-required-string="world" />
+ <div boundbool booldict-prefix-key></div>
+ <div>Tag helper with unmatched bound boolean attributes.</div>
+</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..5f2fdedba9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,45 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_DesignTime
+ {
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::DivTagHelper __DivTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper.BoundRequiredString = "hello";
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_CatchAllTagHelper.BoundRequiredString = "world";
+ __TestNamespace_InputTagHelper.BoundRequiredString = "hello2";
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_InputTagHelper.BoundRequiredString = "world";
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __DivTagHelper.BoundBoolProp = true;
+ __DivTagHelper.BoolDictProp["key"] = true;
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..a16799bfa8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,108 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] MinimizedTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] MinimizedTagHelpers.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [762] MinimizedTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (64:2,29 [34] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (64:2,29 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (70:3,4 [6] MinimizedTagHelpers.cshtml) - Html - <input
+ IntermediateToken - (76:3,10 [13] MinimizedTagHelpers.cshtml) - Html - nottaghelper
+ IntermediateToken - (89:3,23 [3] MinimizedTagHelpers.cshtml) - Html - />
+ IntermediateToken - (92:3,26 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (98:4,4 [59] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (112:4,18 [3] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (112:4,18 [3] MinimizedTagHelpers.cshtml) - Html - btn
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (157:5,39 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (157:5,39 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (163:6,4 [119] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (190:7,18 [3] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (190:7,18 [3] MinimizedTagHelpers.cshtml) - Html - btn
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - input-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (273:7,101 [5] MinimizedTagHelpers.cshtml) - input-bound-required-string - string TestNamespace.InputTagHelper.BoundRequiredString - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (273:7,101 [5] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (273:7,101 [5] MinimizedTagHelpers.cshtml) - Html - hello
+ DefaultTagHelperExecute -
+ HtmlContent - (282:7,110 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (282:7,110 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (288:8,4 [176] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (315:9,18 [3] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (315:9,18 [3] MinimizedTagHelpers.cshtml) - Html - btn
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - input-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (418:11,57 [5] MinimizedTagHelpers.cshtml) - catchall-bound-string - string TestNamespace.CatchAllTagHelper.BoundRequiredString - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (418:11,57 [5] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (418:11,57 [5] MinimizedTagHelpers.cshtml) - Html - world
+ DefaultTagHelperProperty - (454:11,93 [6] MinimizedTagHelpers.cshtml) - input-bound-required-string - string TestNamespace.InputTagHelper.BoundRequiredString - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (454:11,93 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (454:11,93 [6] MinimizedTagHelpers.cshtml) - Html - hello2
+ DefaultTagHelperExecute -
+ HtmlContent - (464:11,103 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (464:11,103 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (470:12,4 [206] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (484:12,18 [3] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (484:12,18 [3] MinimizedTagHelpers.cshtml) - Html - btn
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (529:13,38 [5] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (529:13,38 [5] MinimizedTagHelpers.cshtml) - Html - hello
+ DefaultTagHelperHtmlAttribute - - input-unbound-required - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (578:14,40 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (578:14,40 [6] MinimizedTagHelpers.cshtml) - Html - hello2
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (667:16,40 [5] MinimizedTagHelpers.cshtml) - input-bound-required-string - string TestNamespace.InputTagHelper.BoundRequiredString - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (667:16,40 [5] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (667:16,40 [5] MinimizedTagHelpers.cshtml) - Html - world
+ DefaultTagHelperExecute -
+ HtmlContent - (676:16,49 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (676:16,49 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (682:17,4 [41] MinimizedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperProperty - - boundbool - bool DivTagHelper.BoundBoolProp - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - - booldict-prefix-key - System.Collections.Generic.IDictionary<string, bool> DivTagHelper.BoolDictProp - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (723:17,45 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (723:17,45 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (729:18,4 [62] MinimizedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (734:18,9 [51] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (734:18,9 [51] MinimizedTagHelpers.cshtml) - Html - Tag helper with unmatched bound boolean attributes.
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (791:18,66 [2] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (791:18,66 [2] MinimizedTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..cb760ffd40
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (657:13,37 [17] )
+|"*, TestAssembly"|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..df5a1eb99e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,188 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "29c9ea0bc587afb2f919c7ed7192d6687b534753"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"29c9ea0bc587afb2f919c7ed7192d6687b534753", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("btn"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("input-bound-required-string", "hello", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("catchall-bound-string", "world", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("input-bound-required-string", "hello2", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("catchall-unbound-required", new global::Microsoft.AspNetCore.Html.HtmlString("hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("input-unbound-required", new global::Microsoft.AspNetCore.Html.HtmlString("hello2"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("input-bound-required-string", "world", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::DivTagHelper __DivTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n <input nottaghelper />\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("catchall-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("catchall-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("input-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ __TestNamespace_InputTagHelper.BoundRequiredString = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("catchall-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("input-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ __TestNamespace_CatchAllTagHelper.BoundRequiredString = (string)__tagHelperAttribute_2.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_2);
+ __TestNamespace_InputTagHelper.BoundRequiredString = (string)__tagHelperAttribute_3.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_3);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_4);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("catchall-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ __TestNamespace_InputTagHelper.BoundRequiredString = (string)__tagHelperAttribute_6.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __tagHelperExecutionContext.Add(__DivTagHelper);
+ __DivTagHelper.BoundBoolProp = true;
+ __tagHelperExecutionContext.AddTagHelperAttribute("boundbool", __DivTagHelper.BoundBoolProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ if (__DivTagHelper.BoolDictProp == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("booldict-prefix-key", "DivTagHelper", "BoolDictProp"));
+ }
+ __DivTagHelper.BoolDictProp["key"] = true;
+ __tagHelperExecutionContext.AddTagHelperAttribute("booldict-prefix-key", __DivTagHelper.BoolDictProp["key"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Tag helper with unmatched bound boolean attributes.");
+ }
+ );
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __tagHelperExecutionContext.Add(__DivTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("catchall-unbound-required", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..20205a9756
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MinimizedTagHelpers_Runtime.ir.txt
@@ -0,0 +1,89 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MinimizedTagHelpers_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - btn - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - input-bound-required-string - hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_2 - catchall-bound-string - world - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_3 - input-bound-required-string - hello2 - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_4 - catchall-unbound-required - hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - input-unbound-required - hello2 - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_6 - input-bound-required-string - world - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (35:2,0 [762] MinimizedTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (64:2,29 [34] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (64:2,29 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (70:3,4 [6] MinimizedTagHelpers.cshtml) - Html - <input
+ IntermediateToken - (76:3,10 [13] MinimizedTagHelpers.cshtml) - Html - nottaghelper
+ IntermediateToken - (89:3,23 [3] MinimizedTagHelpers.cshtml) - Html - />
+ IntermediateToken - (92:3,26 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (98:4,4 [59] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (157:5,39 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (157:5,39 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (163:6,4 [119] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - input-unbound-required - HtmlAttributeValueStyle.Minimized
+ PreallocatedTagHelperProperty - (273:7,101 [5] MinimizedTagHelpers.cshtml) - __tagHelperAttribute_1 - input-bound-required-string - BoundRequiredString
+ DefaultTagHelperExecute -
+ HtmlContent - (282:7,110 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (282:7,110 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (288:8,4 [176] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - input-unbound-required - HtmlAttributeValueStyle.Minimized
+ PreallocatedTagHelperProperty - (418:11,57 [5] MinimizedTagHelpers.cshtml) - __tagHelperAttribute_2 - catchall-bound-string - BoundRequiredString
+ PreallocatedTagHelperProperty - (454:11,93 [6] MinimizedTagHelpers.cshtml) - __tagHelperAttribute_3 - input-bound-required-string - BoundRequiredString
+ DefaultTagHelperExecute -
+ HtmlContent - (464:11,103 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (464:11,103 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (470:12,4 [206] MinimizedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_4
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ PreallocatedTagHelperProperty - (667:16,40 [5] MinimizedTagHelpers.cshtml) - __tagHelperAttribute_6 - input-bound-required-string - BoundRequiredString
+ DefaultTagHelperExecute -
+ HtmlContent - (676:16,49 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (676:16,49 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (682:17,4 [41] MinimizedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperProperty - - boundbool - bool DivTagHelper.BoundBoolProp - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - - booldict-prefix-key - System.Collections.Generic.IDictionary<string, bool> DivTagHelper.BoolDictProp - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (723:17,45 [6] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (723:17,45 [6] MinimizedTagHelpers.cshtml) - Html - \n
+ TagHelper - (729:18,4 [62] MinimizedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (734:18,9 [51] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (734:18,9 [51] MinimizedTagHelpers.cshtml) - Html - Tag helper with unmatched bound boolean attributes.
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (791:18,66 [2] MinimizedTagHelpers.cshtml)
+ IntermediateToken - (791:18,66 [2] MinimizedTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - catchall-unbound-required - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml
new file mode 100644
index 0000000000..8387e8a28a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml
@@ -0,0 +1,8 @@
+@{
+ @foreach (var result in (dynamic)Url)
+ {
+ <div>
+ @result.SomeValue.
+ </div>
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ad9d4de7e5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.codegen.cs
@@ -0,0 +1,44 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+ foreach (var result in (dynamic)Url)
+ {
+
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+ __o = result.SomeValue;
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+
+ }
+
+#line default
+#line hidden
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.ir.txt
new file mode 100644
index 0000000000..8e7afb46c6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.ir.txt
@@ -0,0 +1,27 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] NestedCSharp.cshtml)
+ IntermediateToken - (2:0,2 [6] NestedCSharp.cshtml) - CSharp - \n
+ CSharpCode - (9:1,5 [53] NestedCSharp.cshtml)
+ IntermediateToken - (9:1,5 [53] NestedCSharp.cshtml) - CSharp - foreach (var result in (dynamic)Url)\n {\n
+ HtmlContent - (62:3,8 [19] NestedCSharp.cshtml)
+ IntermediateToken - (62:3,8 [5] NestedCSharp.cshtml) - Html - <div>
+ IntermediateToken - (67:3,13 [14] NestedCSharp.cshtml) - Html - \n
+ CSharpExpression - (82:4,13 [16] NestedCSharp.cshtml)
+ IntermediateToken - (82:4,13 [16] NestedCSharp.cshtml) - CSharp - result.SomeValue
+ HtmlContent - (98:4,29 [17] NestedCSharp.cshtml)
+ IntermediateToken - (98:4,29 [11] NestedCSharp.cshtml) - Html - .\n
+ IntermediateToken - (109:5,8 [6] NestedCSharp.cshtml) - Html - </div>
+ CSharpCode - (115:5,14 [7] NestedCSharp.cshtml)
+ IntermediateToken - (115:5,14 [7] NestedCSharp.cshtml) - CSharp - \n }
+ CSharpCode - (122:6,5 [2] NestedCSharp.cshtml)
+ IntermediateToken - (122:6,5 [2] NestedCSharp.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.mappings.txt
new file mode 100644
index 0000000000..a3a8e67f53
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_DesignTime.mappings.txt
@@ -0,0 +1,35 @@
+Source Location: (2:0,2 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml)
+|
+ |
+Generated Location: (649:17,14 [6] )
+|
+ |
+
+Source Location: (9:1,5 [53] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml)
+|foreach (var result in (dynamic)Url)
+ {
+ |
+Generated Location: (750:20,5 [53] )
+|foreach (var result in (dynamic)Url)
+ {
+ |
+
+Source Location: (82:4,13 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml)
+|result.SomeValue|
+Generated Location: (937:27,13 [16] )
+|result.SomeValue|
+
+Source Location: (115:5,14 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml)
+|
+ }|
+Generated Location: (1089:32,14 [7] )
+|
+ }|
+
+Source Location: (122:6,5 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml)
+|
+|
+Generated Location: (1146:37,17 [2] )
+|
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.codegen.cs
new file mode 100644
index 0000000000..1e7b008c95
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.codegen.cs
@@ -0,0 +1,36 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6be69a1b80bfb35325fef427f0709232182e96a8"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"6be69a1b80bfb35325fef427f0709232182e96a8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+ foreach (var result in (dynamic)Url)
+ {
+
+#line default
+#line hidden
+ WriteLiteral(" <div>\r\n ");
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+ Write(result.SomeValue);
+
+#line default
+#line hidden
+ WriteLiteral(".\r\n </div>\r\n");
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp.cshtml"
+ }
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.ir.txt
new file mode 100644
index 0000000000..1c240ea1bd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCSharp_Runtime.ir.txt
@@ -0,0 +1,25 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCSharp_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] NestedCSharp.cshtml)
+ IntermediateToken - (2:0,2 [6] NestedCSharp.cshtml) - CSharp - \n
+ CSharpCode - (9:1,5 [45] NestedCSharp.cshtml)
+ IntermediateToken - (9:1,5 [45] NestedCSharp.cshtml) - CSharp - foreach (var result in (dynamic)Url)\n {\n
+ HtmlContent - (54:3,0 [27] NestedCSharp.cshtml)
+ IntermediateToken - (54:3,0 [8] NestedCSharp.cshtml) - Html -
+ IntermediateToken - (62:3,8 [5] NestedCSharp.cshtml) - Html - <div>
+ IntermediateToken - (67:3,13 [2] NestedCSharp.cshtml) - Html - \n
+ IntermediateToken - (69:4,0 [12] NestedCSharp.cshtml) - Html -
+ CSharpExpression - (82:4,13 [16] NestedCSharp.cshtml)
+ IntermediateToken - (82:4,13 [16] NestedCSharp.cshtml) - CSharp - result.SomeValue
+ HtmlContent - (98:4,29 [19] NestedCSharp.cshtml)
+ IntermediateToken - (98:4,29 [11] NestedCSharp.cshtml) - Html - .\n
+ IntermediateToken - (109:5,8 [6] NestedCSharp.cshtml) - Html - </div>
+ IntermediateToken - (115:5,14 [2] NestedCSharp.cshtml) - Html - \n
+ CSharpCode - (117:6,0 [5] NestedCSharp.cshtml)
+ IntermediateToken - (117:6,0 [5] NestedCSharp.cshtml) - CSharp - }
+ CSharpCode - (122:6,5 [2] NestedCSharp.cshtml)
+ IntermediateToken - (122:6,5 [2] NestedCSharp.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml
new file mode 100644
index 0000000000..070875f5fa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml
@@ -0,0 +1,4 @@
+@if(foo) {
+ @if(bar) {
+ }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.codegen.cs
new file mode 100644
index 0000000000..b3eafcdc00
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.codegen.cs
@@ -0,0 +1,40 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+ if(foo) {
+
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+ if(bar) {
+ }
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.ir.txt
new file mode 100644
index 0000000000..7522731b78
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.ir.txt
@@ -0,0 +1,17 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [15] NestedCodeBlocks.cshtml)
+ IntermediateToken - (1:0,1 [15] NestedCodeBlocks.cshtml) - CSharp - if(foo) {\n
+ CSharpCode - (17:1,5 [16] NestedCodeBlocks.cshtml)
+ IntermediateToken - (17:1,5 [16] NestedCodeBlocks.cshtml) - CSharp - if(bar) {\n }
+ CSharpCode - (33:2,5 [3] NestedCodeBlocks.cshtml)
+ IntermediateToken - (33:2,5 [3] NestedCodeBlocks.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.mappings.txt
new file mode 100644
index 0000000000..36e85f3de3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_DesignTime.mappings.txt
@@ -0,0 +1,21 @@
+Source Location: (1:0,1 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml)
+|if(foo) {
+ |
+Generated Location: (732:18,1 [15] )
+|if(foo) {
+ |
+
+Source Location: (17:1,5 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml)
+|if(bar) {
+ }|
+Generated Location: (877:24,5 [16] )
+|if(bar) {
+ }|
+
+Source Location: (33:2,5 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml)
+|
+}|
+Generated Location: (1023:30,5 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.codegen.cs
new file mode 100644
index 0000000000..7ee3dbc7cf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.codegen.cs
@@ -0,0 +1,36 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d83923f86f1c84f081916ef7308513ab80a65675"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d83923f86f1c84f081916ef7308513ab80a65675", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+ if(foo) {
+
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+ if(bar) {
+ }
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.ir.txt
new file mode 100644
index 0000000000..2c0030ec65
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedCodeBlocks_Runtime.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedCodeBlocks_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [15] NestedCodeBlocks.cshtml)
+ IntermediateToken - (1:0,1 [15] NestedCodeBlocks.cshtml) - CSharp - if(foo) {\n
+ CSharpCode - (17:1,5 [16] NestedCodeBlocks.cshtml)
+ IntermediateToken - (17:1,5 [16] NestedCodeBlocks.cshtml) - CSharp - if(bar) {\n }
+ CSharpCode - (33:2,5 [3] NestedCodeBlocks.cshtml)
+ IntermediateToken - (33:2,5 [3] NestedCodeBlocks.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml
new file mode 100644
index 0000000000..b5fac5a502
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml
@@ -0,0 +1,16 @@
+@addTagHelper "*, TestAssembly"
+
+<script type="text/html">
+ <div data-animation="fade" class="randomNonTagHelperAttribute">
+ <p class="Hello World" data-delay="1000">
+ @for(var i = 0; i < 5; i++) {
+ <script id="nestedScriptTag" type="text/html">
+ <input data-interval="2000 + @ViewBag.DefaultInterval + 1" type="text" checked="true">
+ </script>
+ }
+ <script type="text/javascript">
+ var tag = '<input checked="true">';
+ </script>
+ </p>
+ </div>
+</script> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..0da5daae01
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,56 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedScriptTagTagHelpers_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ for(var i = 0; i < 5; i++) {
+
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ __o = ViewBag.DefaultInterval;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper.Type = "text";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+
+ }
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..cf49fba267
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,87 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedScriptTagTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] NestedScriptTagTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [108] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] NestedScriptTagTagHelpers.cshtml) - Html - \n\n
+ IntermediateToken - (35:2,0 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (42:2,7 [17] NestedScriptTagTagHelpers.cshtml) - Html - type="text/html"
+ IntermediateToken - (59:2,24 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (60:2,25 [6] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (66:3,4 [4] NestedScriptTagTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (70:3,8 [17] NestedScriptTagTagHelpers.cshtml) - Html - data-animation="
+ IntermediateToken - (87:3,25 [4] NestedScriptTagTagHelpers.cshtml) - Html - fade
+ IntermediateToken - (91:3,29 [1] NestedScriptTagTagHelpers.cshtml) - Html - "
+ IntermediateToken - (92:3,30 [36] NestedScriptTagTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (128:3,66 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (129:3,67 [10] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ TagHelper - (139:4,8 [433] NestedScriptTagTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (180:4,49 [14] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (180:4,49 [14] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ CSharpCode - (195:5,13 [46] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (195:5,13 [46] NestedScriptTagTagHelpers.cshtml) - CSharp - for(var i = 0; i < 5; i++) {\n
+ HtmlContent - (241:6,16 [68] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (241:6,16 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (248:6,23 [21] NestedScriptTagTagHelpers.cshtml) - Html - id="nestedScriptTag"
+ IntermediateToken - (269:6,44 [17] NestedScriptTagTagHelpers.cshtml) - Html - type="text/html"
+ IntermediateToken - (286:6,61 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (287:6,62 [22] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ TagHelper - (309:7,20 [86] NestedScriptTagTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - data-interval - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (331:7,42 [7] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (331:7,42 [7] NestedScriptTagTagHelpers.cshtml) - Html - 2000 +
+ CSharpExpression - (339:7,50 [23] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (339:7,50 [23] NestedScriptTagTagHelpers.cshtml) - CSharp - ViewBag.DefaultInterval
+ HtmlContent - (362:7,73 [4] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (362:7,73 [4] NestedScriptTagTagHelpers.cshtml) - Html - + 1
+ DefaultTagHelperProperty - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - Html - text
+ DefaultTagHelperProperty - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - Html - text
+ DefaultTagHelperProperty - (389:7,100 [4] NestedScriptTagTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (389:7,100 [4] NestedScriptTagTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (395:7,106 [27] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (395:7,106 [18] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (413:8,16 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
+ CSharpCode - (422:8,25 [15] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (422:8,25 [15] NestedScriptTagTagHelpers.cshtml) - CSharp - \n }
+ HtmlContent - (437:9,13 [131] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (437:9,13 [14] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (451:10,12 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (458:10,19 [23] NestedScriptTagTagHelpers.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (481:10,42 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (482:10,43 [67] NestedScriptTagTagHelpers.cshtml) - Html - \n var tag = '<input checked="true">';\n
+ IntermediateToken - (549:12,12 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
+ IntermediateToken - (558:12,21 [10] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (149:4,18 [11] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (149:4,18 [11] NestedScriptTagTagHelpers.cshtml) - Html - Hello World
+ DefaultTagHelperHtmlAttribute - - data-delay - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (174:4,43 [4] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (174:4,43 [4] NestedScriptTagTagHelpers.cshtml) - Html - 1000
+ DefaultTagHelperExecute -
+ HtmlContent - (572:13,12 [23] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (572:13,12 [6] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (578:14,4 [6] NestedScriptTagTagHelpers.cshtml) - Html - </div>
+ IntermediateToken - (584:14,10 [2] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (586:15,0 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..59224681d1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,29 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (683:13,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (195:5,13 [46] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml)
+|for(var i = 0; i < 5; i++) {
+ |
+Generated Location: (1131:25,13 [46] )
+|for(var i = 0; i < 5; i++) {
+ |
+
+Source Location: (339:7,50 [23] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml)
+|ViewBag.DefaultInterval|
+Generated Location: (1569:33,50 [23] )
+|ViewBag.DefaultInterval|
+
+Source Location: (389:7,100 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml)
+|true|
+Generated Location: (1975:40,100 [4] )
+|true|
+
+Source Location: (422:8,25 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml)
+|
+ }|
+Generated Location: (2139:45,25 [15] )
+|
+ }|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..2d45fcf415
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,106 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "958c6fc042a8f49499906b46c11bf4b15446c89d"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedScriptTagTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"958c6fc042a8f49499906b46c11bf4b15446c89d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedScriptTagTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-delay", new global::Microsoft.AspNetCore.Html.HtmlString("1000"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<script type=\"text/html\">\r\n <div data-animation=\"fade\" class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n");
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ for(var i = 0; i < 5; i++) {
+
+#line default
+#line hidden
+ WriteLiteral(" <script id=\"nestedScriptTag\" type=\"text/html\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagOnly, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("2000 + ");
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ Write(ViewBag.DefaultInterval);
+
+#line default
+#line hidden
+ WriteLiteral(" + 1");
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("data-interval", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+__TestNamespace_InputTagHelper2.Checked = true;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("checked", __TestNamespace_InputTagHelper2.Checked, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n </script>\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers.cshtml"
+ }
+
+#line default
+#line hidden
+ WriteLiteral(" <script type=\"text/javascript\">\r\n var tag = \'<input checked=\"true\">\';\r\n </script>\r\n ");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n </div>\r\n</script>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..7041d3c6fc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedScriptTagTagHelpers_Runtime.ir.txt
@@ -0,0 +1,80 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedScriptTagTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - data-delay - 1000 - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [106] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (35:2,0 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (42:2,7 [17] NestedScriptTagTagHelpers.cshtml) - Html - type="text/html"
+ IntermediateToken - (59:2,24 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (60:2,25 [6] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (66:3,4 [4] NestedScriptTagTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (70:3,8 [17] NestedScriptTagTagHelpers.cshtml) - Html - data-animation="
+ IntermediateToken - (87:3,25 [4] NestedScriptTagTagHelpers.cshtml) - Html - fade
+ IntermediateToken - (91:3,29 [1] NestedScriptTagTagHelpers.cshtml) - Html - "
+ IntermediateToken - (92:3,30 [36] NestedScriptTagTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (128:3,66 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (129:3,67 [10] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ TagHelper - (139:4,8 [433] NestedScriptTagTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (180:4,49 [2] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (180:4,49 [2] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ CSharpCode - (182:5,0 [12] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (182:5,0 [12] NestedScriptTagTagHelpers.cshtml) - CSharp -
+ CSharpCode - (195:5,13 [30] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (195:5,13 [30] NestedScriptTagTagHelpers.cshtml) - CSharp - for(var i = 0; i < 5; i++) {\n
+ HtmlContent - (225:6,0 [84] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (225:6,0 [16] NestedScriptTagTagHelpers.cshtml) - Html -
+ IntermediateToken - (241:6,16 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (248:6,23 [21] NestedScriptTagTagHelpers.cshtml) - Html - id="nestedScriptTag"
+ IntermediateToken - (269:6,44 [17] NestedScriptTagTagHelpers.cshtml) - Html - type="text/html"
+ IntermediateToken - (286:6,61 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (287:6,62 [22] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ TagHelper - (309:7,20 [86] NestedScriptTagTagHelpers.cshtml) - input - TagMode.StartTagOnly
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - data-interval - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (331:7,42 [7] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (331:7,42 [7] NestedScriptTagTagHelpers.cshtml) - Html - 2000 +
+ CSharpExpression - (339:7,50 [23] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (339:7,50 [23] NestedScriptTagTagHelpers.cshtml) - CSharp - ViewBag.DefaultInterval
+ HtmlContent - (362:7,73 [4] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (362:7,73 [4] NestedScriptTagTagHelpers.cshtml) - Html - + 1
+ PreallocatedTagHelperProperty - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ PreallocatedTagHelperProperty - (374:7,85 [4] NestedScriptTagTagHelpers.cshtml) - __tagHelperAttribute_0 - type - Type
+ DefaultTagHelperProperty - (389:7,100 [4] NestedScriptTagTagHelpers.cshtml) - checked - bool TestNamespace.InputTagHelper2.Checked - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (389:7,100 [4] NestedScriptTagTagHelpers.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (395:7,106 [29] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (395:7,106 [18] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (413:8,16 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
+ IntermediateToken - (422:8,25 [2] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ CSharpCode - (424:9,0 [15] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (424:9,0 [15] NestedScriptTagTagHelpers.cshtml) - CSharp - }\n
+ HtmlContent - (439:10,0 [129] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (439:10,0 [12] NestedScriptTagTagHelpers.cshtml) - Html -
+ IntermediateToken - (451:10,12 [7] NestedScriptTagTagHelpers.cshtml) - Html - <script
+ IntermediateToken - (458:10,19 [23] NestedScriptTagTagHelpers.cshtml) - Html - type="text/javascript"
+ IntermediateToken - (481:10,42 [1] NestedScriptTagTagHelpers.cshtml) - Html - >
+ IntermediateToken - (482:10,43 [67] NestedScriptTagTagHelpers.cshtml) - Html - \n var tag = '<input checked="true">';\n
+ IntermediateToken - (549:12,12 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
+ IntermediateToken - (558:12,21 [10] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ HtmlContent - (572:13,12 [23] NestedScriptTagTagHelpers.cshtml)
+ IntermediateToken - (572:13,12 [6] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (578:14,4 [6] NestedScriptTagTagHelpers.cshtml) - Html - </div>
+ IntermediateToken - (584:14,10 [2] NestedScriptTagTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (586:15,0 [9] NestedScriptTagTagHelpers.cshtml) - Html - </script>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml
new file mode 100644
index 0000000000..e6637b03fa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml
@@ -0,0 +1,5 @@
+@addTagHelper *, TestAssembly
+<span someattr>Hola</span>
+<div unbound="foo">
+ <input value=Hello type='text' />
+</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..ea880b7745
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,33 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedTagHelpers_DesignTime
+ {
+ private global::SpanTagHelper __SpanTagHelper;
+ private global::DivTagHelper __DivTagHelper;
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __SpanTagHelper = CreateTagHelper<global::SpanTagHelper>();
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __InputTagHelper.FooProp = "Hello";
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..4a4b5e257d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,48 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::SpanTagHelper - __SpanTagHelper
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] NestedTagHelpers.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (29:0,29 [2] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (31:1,0 [26] NestedTagHelpers.cshtml) - span - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (46:1,15 [4] NestedTagHelpers.cshtml)
+ IntermediateToken - (46:1,15 [4] NestedTagHelpers.cshtml) - Html - Hola
+ DefaultTagHelperCreate - - SpanTagHelper
+ DefaultTagHelperHtmlAttribute - - someattr - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (57:1,26 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (57:1,26 [2] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (59:2,0 [66] NestedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (78:2,19 [6] NestedTagHelpers.cshtml)
+ IntermediateToken - (78:2,19 [6] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (84:3,4 [33] NestedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (97:3,17 [5] NestedTagHelpers.cshtml) - value - string InputTagHelper.FooProp - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (97:3,17 [5] NestedTagHelpers.cshtml)
+ IntermediateToken - (97:3,17 [5] NestedTagHelpers.cshtml) - Html - Hello
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (109:3,29 [4] NestedTagHelpers.cshtml)
+ IntermediateToken - (109:3,29 [4] NestedTagHelpers.cshtml) - Html - text
+ DefaultTagHelperExecute -
+ HtmlContent - (117:3,37 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (117:3,37 [2] NestedTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperHtmlAttribute - - unbound - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (73:2,14 [3] NestedTagHelpers.cshtml)
+ IntermediateToken - (73:2,14 [3] NestedTagHelpers.cshtml) - Html - foo
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..0cc715d741
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml)
+|*, TestAssembly|
+Generated Location: (591:13,38 [15] )
+|*, TestAssembly|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..d7752b8aca
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,89 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5e63d5fe37100e65dfcf39dd1c542eb697b624db"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5e63d5fe37100e65dfcf39dd1c542eb697b624db", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", "Hello", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("text"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("unbound", new global::Microsoft.AspNetCore.Html.HtmlString("foo"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::SpanTagHelper __SpanTagHelper;
+ private global::DivTagHelper __DivTagHelper;
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("span", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Hola");
+ }
+ );
+ __SpanTagHelper = CreateTagHelper<global::SpanTagHelper>();
+ __tagHelperExecutionContext.Add(__SpanTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("someattr", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __tagHelperExecutionContext.Add(__InputTagHelper);
+ __InputTagHelper.FooProp = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ );
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __tagHelperExecutionContext.Add(__DivTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..f4c6001b80
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NestedTagHelpers_Runtime.ir.txt
@@ -0,0 +1,37 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NestedTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::SpanTagHelper - __SpanTagHelper
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ TagHelper - (31:1,0 [26] NestedTagHelpers.cshtml) - span - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (46:1,15 [4] NestedTagHelpers.cshtml)
+ IntermediateToken - (46:1,15 [4] NestedTagHelpers.cshtml) - Html - Hola
+ DefaultTagHelperCreate - - SpanTagHelper
+ DefaultTagHelperHtmlAttribute - - someattr - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (57:1,26 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (57:1,26 [2] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (59:2,0 [66] NestedTagHelpers.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (78:2,19 [6] NestedTagHelpers.cshtml)
+ IntermediateToken - (78:2,19 [6] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (84:3,4 [33] NestedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ PreallocatedTagHelperProperty - (97:3,17 [5] NestedTagHelpers.cshtml) - __tagHelperAttribute_0 - value - FooProp
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (117:3,37 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (117:3,37 [2] NestedTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - DivTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml
new file mode 100644
index 0000000000..36e96c46b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml
@@ -0,0 +1,38 @@
+@{
+ int i = 1;
+}
+
+@while(i <= 10) {
+ <p>Hello from C#, #@(i)</p>
+ i += 1;
+}
+
+@if(i == 11) {
+ <p>We wrote 10 lines!</p>
+}
+
+@switch(i) {
+ case 11:
+ <p>No really, we wrote 10 lines!</p>
+ break;
+ default:
+ <p>Actually, we didn't...</p>
+ break;
+}
+
+@for(int j = 1; j <= 10; j += 2) {
+ <p>Hello again from C#, #@(j)</p>
+}
+
+@try {
+ <p>That time, we wrote 5 lines!</p>
+} catch(Exception ex) {
+ <p>Oh no! An error occurred: @(ex.Message)</p>
+}
+
+@* With has no equivalent in C# *@
+<p>i is now @i</p>
+
+@lock(new object()) {
+ <p>This block is locked, for your security!</p>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.codegen.cs
new file mode 100644
index 0000000000..a800b83828
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.codegen.cs
@@ -0,0 +1,140 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NoLinePragmas_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+ int i = 1;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ while(i <= 10) {
+
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+ i += 1;
+}
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ if(i == 11) {
+
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ switch(i) {
+ case 11:
+
+
+#line default
+#line hidden
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+ break;
+ default:
+
+
+#line default
+#line hidden
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+ break;
+}
+
+#line default
+#line hidden
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+
+#line default
+#line hidden
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ __o = j;
+
+#line default
+#line hidden
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+}
+
+#line default
+#line hidden
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ try {
+
+
+#line default
+#line hidden
+#line 28 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+} catch(Exception ex) {
+
+
+#line default
+#line hidden
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ __o = ex.Message;
+
+#line default
+#line hidden
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+}
+
+
+#line default
+#line hidden
+
+#line 34 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ __o = i;
+
+#line default
+#line hidden
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ lock(new object()) {
+
+
+#line default
+#line hidden
+#line 37 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.ir.txt
new file mode 100644
index 0000000000..9ed035c3c7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.ir.txt
@@ -0,0 +1,103 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NoLinePragmas_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [18] NoLinePragmas.cshtml)
+ IntermediateToken - (2:0,2 [18] NoLinePragmas.cshtml) - CSharp - \n int i = 1;\n
+ HtmlContent - (23:3,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (23:3,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (26:4,1 [22] NoLinePragmas.cshtml)
+ IntermediateToken - (26:4,1 [22] NoLinePragmas.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (48:5,4 [19] NoLinePragmas.cshtml)
+ IntermediateToken - (48:5,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (51:5,7 [16] NoLinePragmas.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:5,25 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (69:5,25 [1] NoLinePragmas.cshtml) - CSharp - i
+ HtmlContent - (71:5,27 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (71:5,27 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (75:5,31 [16] NoLinePragmas.cshtml)
+ IntermediateToken - (75:5,31 [16] NoLinePragmas.cshtml) - CSharp - \n i += 1;\n}
+ HtmlContent - (91:7,1 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (91:7,1 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (96:9,1 [19] NoLinePragmas.cshtml)
+ IntermediateToken - (96:9,1 [19] NoLinePragmas.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (115:10,4 [25] NoLinePragmas.cshtml)
+ IntermediateToken - (115:10,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (118:10,7 [18] NoLinePragmas.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (136:10,25 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (140:10,29 [3] NoLinePragmas.cshtml)
+ IntermediateToken - (140:10,29 [3] NoLinePragmas.cshtml) - CSharp - \n}
+ HtmlContent - (143:11,1 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (143:11,1 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (148:13,1 [35] NoLinePragmas.cshtml)
+ IntermediateToken - (148:13,1 [35] NoLinePragmas.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (183:15,8 [36] NoLinePragmas.cshtml)
+ IntermediateToken - (183:15,8 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (186:15,11 [29] NoLinePragmas.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (215:15,40 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (219:15,44 [40] NoLinePragmas.cshtml)
+ IntermediateToken - (219:15,44 [40] NoLinePragmas.cshtml) - CSharp - \n break;\n default:\n
+ HtmlContent - (259:18,8 [29] NoLinePragmas.cshtml)
+ IntermediateToken - (259:18,8 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (262:18,11 [22] NoLinePragmas.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (284:18,33 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (288:18,37 [19] NoLinePragmas.cshtml)
+ IntermediateToken - (288:18,37 [19] NoLinePragmas.cshtml) - CSharp - \n break;\n}
+ HtmlContent - (307:20,1 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (307:20,1 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (312:22,1 [39] NoLinePragmas.cshtml)
+ IntermediateToken - (312:22,1 [39] NoLinePragmas.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (351:23,4 [25] NoLinePragmas.cshtml)
+ IntermediateToken - (351:23,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (354:23,7 [22] NoLinePragmas.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (378:23,31 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (378:23,31 [1] NoLinePragmas.cshtml) - CSharp - j
+ HtmlContent - (380:23,33 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (380:23,33 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (384:23,37 [3] NoLinePragmas.cshtml)
+ IntermediateToken - (384:23,37 [3] NoLinePragmas.cshtml) - CSharp - \n}
+ HtmlContent - (387:24,1 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (387:24,1 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (392:26,1 [11] NoLinePragmas.cshtml)
+ IntermediateToken - (392:26,1 [11] NoLinePragmas.cshtml) - CSharp - try {\n
+ HtmlContent - (403:27,4 [35] NoLinePragmas.cshtml)
+ IntermediateToken - (403:27,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (406:27,7 [28] NoLinePragmas.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (434:27,35 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (438:27,39 [31] NoLinePragmas.cshtml)
+ IntermediateToken - (438:27,39 [31] NoLinePragmas.cshtml) - CSharp - \n} catch(Exception ex) {\n
+ HtmlContent - (469:29,4 [29] NoLinePragmas.cshtml)
+ IntermediateToken - (469:29,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (472:29,7 [26] NoLinePragmas.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (500:29,35 [10] NoLinePragmas.cshtml)
+ IntermediateToken - (500:29,35 [10] NoLinePragmas.cshtml) - CSharp - ex.Message
+ HtmlContent - (511:29,46 [4] NoLinePragmas.cshtml)
+ IntermediateToken - (511:29,46 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (515:29,50 [7] NoLinePragmas.cshtml)
+ IntermediateToken - (515:29,50 [7] NoLinePragmas.cshtml) - CSharp - \n}\n\n
+ CSharpCode - (556:32,34 [0] NoLinePragmas.cshtml)
+ IntermediateToken - (556:32,34 [0] NoLinePragmas.cshtml) - CSharp -
+ HtmlContent - (556:32,34 [14] NoLinePragmas.cshtml)
+ IntermediateToken - (556:32,34 [2] NoLinePragmas.cshtml) - Html - \n
+ IntermediateToken - (558:33,0 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (561:33,3 [9] NoLinePragmas.cshtml) - Html - i is now
+ CSharpExpression - (571:33,13 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (571:33,13 [1] NoLinePragmas.cshtml) - CSharp - i
+ HtmlContent - (572:33,14 [8] NoLinePragmas.cshtml)
+ IntermediateToken - (572:33,14 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (576:33,18 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (581:35,1 [26] NoLinePragmas.cshtml)
+ IntermediateToken - (581:35,1 [26] NoLinePragmas.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (607:36,4 [47] NoLinePragmas.cshtml)
+ IntermediateToken - (607:36,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (610:36,7 [40] NoLinePragmas.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (650:36,47 [4] NoLinePragmas.cshtml) - Html - </p>
+ CSharpCode - (654:36,51 [3] NoLinePragmas.cshtml)
+ IntermediateToken - (654:36,51 [3] NoLinePragmas.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.mappings.txt
new file mode 100644
index 0000000000..349b695abd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_DesignTime.mappings.txt
@@ -0,0 +1,148 @@
+Source Location: (2:0,2 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+ int i = 1;
+|
+Generated Location: (727:18,2 [18] )
+|
+ int i = 1;
+|
+
+Source Location: (26:4,1 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|while(i <= 10) {
+ |
+Generated Location: (866:24,1 [22] )
+|while(i <= 10) {
+ |
+
+Source Location: (69:5,25 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|i|
+Generated Location: (1035:30,25 [1] )
+|i|
+
+Source Location: (75:5,31 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+ i += 1;
+}|
+Generated Location: (1190:35,31 [16] )
+|
+ i += 1;
+}|
+
+Source Location: (96:9,1 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|if(i == 11) {
+ |
+Generated Location: (1330:42,1 [19] )
+|if(i == 11) {
+ |
+
+Source Location: (140:10,29 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+}|
+Generated Location: (1501:48,29 [3] )
+|
+}|
+
+Source Location: (148:13,1 [35] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|switch(i) {
+ case 11:
+ |
+Generated Location: (1628:54,1 [35] )
+|switch(i) {
+ case 11:
+ |
+
+Source Location: (219:15,44 [40] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+ break;
+ default:
+ |
+Generated Location: (1830:61,44 [40] )
+|
+ break;
+ default:
+ |
+
+Source Location: (288:18,37 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+ break;
+}|
+Generated Location: (2030:69,37 [19] )
+|
+ break;
+}|
+
+Source Location: (312:22,1 [39] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|for(int j = 1; j <= 10; j += 2) {
+ |
+Generated Location: (2173:76,1 [39] )
+|for(int j = 1; j <= 10; j += 2) {
+ |
+
+Source Location: (378:23,31 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|j|
+Generated Location: (2366:82,31 [1] )
+|j|
+
+Source Location: (384:23,37 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+}|
+Generated Location: (2528:87,37 [3] )
+|
+}|
+
+Source Location: (392:26,1 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|try {
+ |
+Generated Location: (2655:93,1 [11] )
+|try {
+ |
+
+Source Location: (438:27,39 [31] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+} catch(Exception ex) {
+ |
+Generated Location: (2828:99,39 [31] )
+|
+} catch(Exception ex) {
+ |
+
+Source Location: (500:29,35 [10] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|ex.Message|
+Generated Location: (3017:106,35 [10] )
+|ex.Message|
+
+Source Location: (515:29,50 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+}
+
+|
+Generated Location: (3201:111,50 [7] )
+|
+}
+
+|
+
+Source Location: (556:32,34 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+||
+Generated Location: (3285:117,46 [0] )
+||
+
+Source Location: (571:33,13 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|i|
+Generated Location: (3390:119,13 [1] )
+|i|
+
+Source Location: (581:35,1 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|lock(new object()) {
+ |
+Generated Location: (3516:124,1 [26] )
+|lock(new object()) {
+ |
+
+Source Location: (654:36,51 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml)
+|
+}|
+Generated Location: (3716:130,51 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.codegen.cs
new file mode 100644
index 0000000000..81891b57b7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.codegen.cs
@@ -0,0 +1,137 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c6fa3992fa56644768995c97941d682d90f6d8ec"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NoLinePragmas_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"c6fa3992fa56644768995c97941d682d90f6d8ec", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NoLinePragmas_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+
+ int i = 1;
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ while(i <= 10) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello from C#, #");
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ i += 1;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ if(i == 11) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>We wrote 10 lines!</p>\r\n");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ switch(i) {
+ case 11:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>No really, we wrote 10 lines!</p>\r\n");
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ break;
+ default:
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Actually, we didn\'t...</p>\r\n");
+#line 20 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ break;
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 23 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ for(int j = 1; j <= 10; j += 2) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Hello again from C#, #");
+#line 24 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ Write(j);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 25 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+}
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ try {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>That time, we wrote 5 lines!</p>\r\n");
+#line 29 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+} catch(Exception ex) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>Oh no! An error occurred: ");
+#line 30 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ Write(ex.Message);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n");
+#line 31 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+}
+
+
+#line default
+#line hidden
+ WriteLiteral("<p>i is now ");
+#line 34 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ Write(i);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n\r\n");
+#line 36 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+ lock(new object()) {
+
+#line default
+#line hidden
+ WriteLiteral(" <p>This block is locked, for your security!</p>\r\n");
+#line 38 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.ir.txt
new file mode 100644
index 0000000000..133177b5c4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NoLinePragmas_Runtime.ir.txt
@@ -0,0 +1,113 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NoLinePragmas_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [18] NoLinePragmas.cshtml)
+ IntermediateToken - (2:0,2 [18] NoLinePragmas.cshtml) - CSharp - \n int i = 1;\n
+ HtmlContent - (23:3,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (23:3,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (26:4,1 [18] NoLinePragmas.cshtml)
+ IntermediateToken - (26:4,1 [18] NoLinePragmas.cshtml) - CSharp - while(i <= 10) {\n
+ HtmlContent - (44:5,0 [23] NoLinePragmas.cshtml)
+ IntermediateToken - (44:5,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (48:5,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (51:5,7 [16] NoLinePragmas.cshtml) - Html - Hello from C#, #
+ CSharpExpression - (69:5,25 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (69:5,25 [1] NoLinePragmas.cshtml) - CSharp - i
+ HtmlContent - (71:5,27 [6] NoLinePragmas.cshtml)
+ IntermediateToken - (71:5,27 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (75:5,31 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (77:6,0 [16] NoLinePragmas.cshtml)
+ IntermediateToken - (77:6,0 [16] NoLinePragmas.cshtml) - CSharp - i += 1;\n}\n
+ HtmlContent - (93:8,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (93:8,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (96:9,1 [15] NoLinePragmas.cshtml)
+ IntermediateToken - (96:9,1 [15] NoLinePragmas.cshtml) - CSharp - if(i == 11) {\n
+ HtmlContent - (111:10,0 [31] NoLinePragmas.cshtml)
+ IntermediateToken - (111:10,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (115:10,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (118:10,7 [18] NoLinePragmas.cshtml) - Html - We wrote 10 lines!
+ IntermediateToken - (136:10,25 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (140:10,29 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (142:11,0 [3] NoLinePragmas.cshtml)
+ IntermediateToken - (142:11,0 [3] NoLinePragmas.cshtml) - CSharp - }\n
+ HtmlContent - (145:12,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (145:12,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (148:13,1 [27] NoLinePragmas.cshtml)
+ IntermediateToken - (148:13,1 [27] NoLinePragmas.cshtml) - CSharp - switch(i) {\n case 11:\n
+ HtmlContent - (175:15,0 [46] NoLinePragmas.cshtml)
+ IntermediateToken - (175:15,0 [8] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (183:15,8 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (186:15,11 [29] NoLinePragmas.cshtml) - Html - No really, we wrote 10 lines!
+ IntermediateToken - (215:15,40 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (219:15,44 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (221:16,0 [30] NoLinePragmas.cshtml)
+ IntermediateToken - (221:16,0 [30] NoLinePragmas.cshtml) - CSharp - break;\n default:\n
+ HtmlContent - (251:18,0 [39] NoLinePragmas.cshtml)
+ IntermediateToken - (251:18,0 [8] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (259:18,8 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (262:18,11 [22] NoLinePragmas.cshtml) - Html - Actually, we didn't...
+ IntermediateToken - (284:18,33 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (288:18,37 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (290:19,0 [19] NoLinePragmas.cshtml)
+ IntermediateToken - (290:19,0 [19] NoLinePragmas.cshtml) - CSharp - break;\n}\n
+ HtmlContent - (309:21,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (309:21,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (312:22,1 [35] NoLinePragmas.cshtml)
+ IntermediateToken - (312:22,1 [35] NoLinePragmas.cshtml) - CSharp - for(int j = 1; j <= 10; j += 2) {\n
+ HtmlContent - (347:23,0 [29] NoLinePragmas.cshtml)
+ IntermediateToken - (347:23,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (351:23,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (354:23,7 [22] NoLinePragmas.cshtml) - Html - Hello again from C#, #
+ CSharpExpression - (378:23,31 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (378:23,31 [1] NoLinePragmas.cshtml) - CSharp - j
+ HtmlContent - (380:23,33 [6] NoLinePragmas.cshtml)
+ IntermediateToken - (380:23,33 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (384:23,37 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (386:24,0 [3] NoLinePragmas.cshtml)
+ IntermediateToken - (386:24,0 [3] NoLinePragmas.cshtml) - CSharp - }\n
+ HtmlContent - (389:25,0 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (389:25,0 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (392:26,1 [7] NoLinePragmas.cshtml)
+ IntermediateToken - (392:26,1 [7] NoLinePragmas.cshtml) - CSharp - try {\n
+ HtmlContent - (399:27,0 [41] NoLinePragmas.cshtml)
+ IntermediateToken - (399:27,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (403:27,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (406:27,7 [28] NoLinePragmas.cshtml) - Html - That time, we wrote 5 lines!
+ IntermediateToken - (434:27,35 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (438:27,39 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (440:28,0 [25] NoLinePragmas.cshtml)
+ IntermediateToken - (440:28,0 [25] NoLinePragmas.cshtml) - CSharp - } catch(Exception ex) {\n
+ HtmlContent - (465:29,0 [33] NoLinePragmas.cshtml)
+ IntermediateToken - (465:29,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (469:29,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (472:29,7 [26] NoLinePragmas.cshtml) - Html - Oh no! An error occurred:
+ CSharpExpression - (500:29,35 [10] NoLinePragmas.cshtml)
+ IntermediateToken - (500:29,35 [10] NoLinePragmas.cshtml) - CSharp - ex.Message
+ HtmlContent - (511:29,46 [6] NoLinePragmas.cshtml)
+ IntermediateToken - (511:29,46 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (515:29,50 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (517:30,0 [5] NoLinePragmas.cshtml)
+ IntermediateToken - (517:30,0 [5] NoLinePragmas.cshtml) - CSharp - }\n\n
+ CSharpCode - (556:32,34 [2] NoLinePragmas.cshtml)
+ IntermediateToken - (556:32,34 [2] NoLinePragmas.cshtml) - CSharp - \n
+ HtmlContent - (558:33,0 [12] NoLinePragmas.cshtml)
+ IntermediateToken - (558:33,0 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (561:33,3 [9] NoLinePragmas.cshtml) - Html - i is now
+ CSharpExpression - (571:33,13 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (571:33,13 [1] NoLinePragmas.cshtml) - CSharp - i
+ HtmlContent - (572:33,14 [8] NoLinePragmas.cshtml)
+ IntermediateToken - (572:33,14 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (576:33,18 [4] NoLinePragmas.cshtml) - Html - \n\n
+ CSharpCode - (581:35,1 [22] NoLinePragmas.cshtml)
+ IntermediateToken - (581:35,1 [22] NoLinePragmas.cshtml) - CSharp - lock(new object()) {\n
+ HtmlContent - (603:36,0 [53] NoLinePragmas.cshtml)
+ IntermediateToken - (603:36,0 [4] NoLinePragmas.cshtml) - Html -
+ IntermediateToken - (607:36,4 [3] NoLinePragmas.cshtml) - Html - <p>
+ IntermediateToken - (610:36,7 [40] NoLinePragmas.cshtml) - Html - This block is locked, for your security!
+ IntermediateToken - (650:36,47 [4] NoLinePragmas.cshtml) - Html - </p>
+ IntermediateToken - (654:36,51 [2] NoLinePragmas.cshtml) - Html - \n
+ CSharpCode - (656:37,0 [1] NoLinePragmas.cshtml)
+ IntermediateToken - (656:37,0 [1] NoLinePragmas.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml
new file mode 100644
index 0000000000..fa87620317
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml
@@ -0,0 +1,11 @@
+@{
+ @ViewBag?.Data
+ @ViewBag.IntIndexer?[0]
+ @ViewBag.StrIndexer?["key"]
+ @ViewBag?.Method(Value?[23]?.More)?["key"]
+}
+
+@ViewBag?.Data
+@ViewBag.IntIndexer?[0]
+@ViewBag.StrIndexer?["key"]
+@ViewBag?.Method(Value?[23]?.More)?["key"] \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.codegen.cs
new file mode 100644
index 0000000000..a380c6449e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.codegen.cs
@@ -0,0 +1,72 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NullConditionalExpressions_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag?.Data;
+
+#line default
+#line hidden
+
+
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag.IntIndexer?[0];
+
+#line default
+#line hidden
+
+
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag.StrIndexer?["key"];
+
+#line default
+#line hidden
+
+
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag?.Method(Value?[23]?.More)?["key"];
+
+#line default
+#line hidden
+
+
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag?.Data;
+
+#line default
+#line hidden
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag.IntIndexer?[0];
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag.StrIndexer?["key"];
+
+#line default
+#line hidden
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+__o = ViewBag?.Method(Value?[23]?.More)?["key"];
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.ir.txt
new file mode 100644
index 0000000000..58e35883ee
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.ir.txt
@@ -0,0 +1,45 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NullConditionalExpressions_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (2:0,2 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (9:1,5 [13] NullConditionalExpressions.cshtml)
+ IntermediateToken - (9:1,5 [13] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Data
+ CSharpCode - (22:1,18 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (22:1,18 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (29:2,5 [22] NullConditionalExpressions.cshtml)
+ IntermediateToken - (29:2,5 [22] NullConditionalExpressions.cshtml) - CSharp - ViewBag.IntIndexer?[0]
+ CSharpCode - (51:2,27 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (51:2,27 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (58:3,5 [26] NullConditionalExpressions.cshtml)
+ IntermediateToken - (58:3,5 [26] NullConditionalExpressions.cshtml) - CSharp - ViewBag.StrIndexer?["key"]
+ CSharpCode - (84:3,31 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (84:3,31 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (91:4,5 [41] NullConditionalExpressions.cshtml)
+ IntermediateToken - (91:4,5 [41] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Method(Value?[23]?.More)?["key"]
+ CSharpCode - (132:4,46 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (132:4,46 [2] NullConditionalExpressions.cshtml) - CSharp - \n
+ HtmlContent - (137:6,0 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (137:6,0 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (140:7,1 [13] NullConditionalExpressions.cshtml)
+ IntermediateToken - (140:7,1 [13] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Data
+ HtmlContent - (153:7,14 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (153:7,14 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (156:8,1 [22] NullConditionalExpressions.cshtml)
+ IntermediateToken - (156:8,1 [22] NullConditionalExpressions.cshtml) - CSharp - ViewBag.IntIndexer?[0]
+ HtmlContent - (178:8,23 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (178:8,23 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (181:9,1 [26] NullConditionalExpressions.cshtml)
+ IntermediateToken - (181:9,1 [26] NullConditionalExpressions.cshtml) - CSharp - ViewBag.StrIndexer?["key"]
+ HtmlContent - (207:9,27 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (207:9,27 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (210:10,1 [41] NullConditionalExpressions.cshtml)
+ IntermediateToken - (210:10,1 [41] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Method(Value?[23]?.More)?["key"]
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.mappings.txt
new file mode 100644
index 0000000000..0f7b77a97c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_DesignTime.mappings.txt
@@ -0,0 +1,75 @@
+Source Location: (2:0,2 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|
+ |
+Generated Location: (663:17,14 [6] )
+|
+ |
+
+Source Location: (9:1,5 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag?.Data|
+Generated Location: (779:20,6 [13] )
+|ViewBag?.Data|
+
+Source Location: (22:1,18 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|
+ |
+Generated Location: (856:24,30 [6] )
+|
+ |
+
+Source Location: (29:2,5 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag.IntIndexer?[0]|
+Generated Location: (972:27,6 [22] )
+|ViewBag.IntIndexer?[0]|
+
+Source Location: (51:2,27 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|
+ |
+Generated Location: (1067:31,39 [6] )
+|
+ |
+
+Source Location: (58:3,5 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag.StrIndexer?["key"]|
+Generated Location: (1183:34,6 [26] )
+|ViewBag.StrIndexer?["key"]|
+
+Source Location: (84:3,31 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|
+ |
+Generated Location: (1286:38,43 [6] )
+|
+ |
+
+Source Location: (91:4,5 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag?.Method(Value?[23]?.More)?["key"]|
+Generated Location: (1402:41,6 [41] )
+|ViewBag?.Method(Value?[23]?.More)?["key"]|
+
+Source Location: (132:4,46 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|
+|
+Generated Location: (1535:45,58 [2] )
+|
+|
+
+Source Location: (140:7,1 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag?.Data|
+Generated Location: (1647:48,6 [13] )
+|ViewBag?.Data|
+
+Source Location: (156:8,1 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag.IntIndexer?[0]|
+Generated Location: (1802:53,6 [22] )
+|ViewBag.IntIndexer?[0]|
+
+Source Location: (181:9,1 [26] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag.StrIndexer?["key"]|
+Generated Location: (1967:58,6 [26] )
+|ViewBag.StrIndexer?["key"]|
+
+Source Location: (210:10,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml)
+|ViewBag?.Method(Value?[23]?.More)?["key"]|
+Generated Location: (2136:63,6 [41] )
+|ViewBag?.Method(Value?[23]?.More)?["key"]|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.codegen.cs
new file mode 100644
index 0000000000..eb8bd3a54e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.codegen.cs
@@ -0,0 +1,62 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "c76f9ddb44b2830babd64c0afeaa96aba6a6ae27"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NullConditionalExpressions_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"c76f9ddb44b2830babd64c0afeaa96aba6a6ae27", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NullConditionalExpressions_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag?.Data);
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag.IntIndexer?[0]);
+
+#line default
+#line hidden
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag.StrIndexer?["key"]);
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag?.Method(Value?[23]?.More)?["key"]);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag?.Data);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag.IntIndexer?[0]);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag.StrIndexer?["key"]);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions.cshtml"
+Write(ViewBag?.Method(Value?[23]?.More)?["key"]);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.ir.txt
new file mode 100644
index 0000000000..8fd7d3dc26
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/NullConditionalExpressions_Runtime.ir.txt
@@ -0,0 +1,40 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_NullConditionalExpressions_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (2:0,2 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (9:1,5 [13] NullConditionalExpressions.cshtml)
+ IntermediateToken - (9:1,5 [13] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Data
+ CSharpCode - (22:1,18 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (22:1,18 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (29:2,5 [22] NullConditionalExpressions.cshtml)
+ IntermediateToken - (29:2,5 [22] NullConditionalExpressions.cshtml) - CSharp - ViewBag.IntIndexer?[0]
+ CSharpCode - (51:2,27 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (51:2,27 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (58:3,5 [26] NullConditionalExpressions.cshtml)
+ IntermediateToken - (58:3,5 [26] NullConditionalExpressions.cshtml) - CSharp - ViewBag.StrIndexer?["key"]
+ CSharpCode - (84:3,31 [6] NullConditionalExpressions.cshtml)
+ IntermediateToken - (84:3,31 [6] NullConditionalExpressions.cshtml) - CSharp - \n
+ CSharpExpression - (91:4,5 [41] NullConditionalExpressions.cshtml)
+ IntermediateToken - (91:4,5 [41] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Method(Value?[23]?.More)?["key"]
+ CSharpCode - (132:4,46 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (132:4,46 [2] NullConditionalExpressions.cshtml) - CSharp - \n
+ HtmlContent - (137:6,0 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (137:6,0 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (140:7,1 [13] NullConditionalExpressions.cshtml)
+ IntermediateToken - (140:7,1 [13] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Data
+ HtmlContent - (153:7,14 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (153:7,14 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (156:8,1 [22] NullConditionalExpressions.cshtml)
+ IntermediateToken - (156:8,1 [22] NullConditionalExpressions.cshtml) - CSharp - ViewBag.IntIndexer?[0]
+ HtmlContent - (178:8,23 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (178:8,23 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (181:9,1 [26] NullConditionalExpressions.cshtml)
+ IntermediateToken - (181:9,1 [26] NullConditionalExpressions.cshtml) - CSharp - ViewBag.StrIndexer?["key"]
+ HtmlContent - (207:9,27 [2] NullConditionalExpressions.cshtml)
+ IntermediateToken - (207:9,27 [2] NullConditionalExpressions.cshtml) - Html - \n
+ CSharpExpression - (210:10,1 [41] NullConditionalExpressions.cshtml)
+ IntermediateToken - (210:10,1 [41] NullConditionalExpressions.cshtml) - CSharp - ViewBag?.Method(Value?[23]?.More)?["key"]
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml
new file mode 100644
index 0000000000..33162eb90b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml
@@ -0,0 +1,5 @@
+<html>
+<body>
+@if (true) {
+</body>
+</html> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.codegen.cs
new file mode 100644
index 0000000000..cbf0fbd1b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.codegen.cs
@@ -0,0 +1,30 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_OpenedIf_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..49f293ec33
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.diagnostics.txt
@@ -0,0 +1,3 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(4,3): Error RZ1026: Encountered end tag "body" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(5,3): Error RZ1026: Encountered end tag "html" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(3,2): Error RZ1006: The if block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.ir.txt
new file mode 100644
index 0000000000..c7c6a63d11
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.ir.txt
@@ -0,0 +1,26 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_OpenedIf_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [16] OpenedIf.cshtml)
+ IntermediateToken - (0:0,0 [6] OpenedIf.cshtml) - Html - <html>
+ IntermediateToken - (6:0,6 [2] OpenedIf.cshtml) - Html - \n
+ IntermediateToken - (8:1,0 [6] OpenedIf.cshtml) - Html - <body>
+ IntermediateToken - (14:1,6 [2] OpenedIf.cshtml) - Html - \n
+ CSharpCode - (17:2,1 [14] OpenedIf.cshtml)
+ IntermediateToken - (17:2,1 [14] OpenedIf.cshtml) - CSharp - if (true) { \n
+ HtmlContent - (31:3,0 [7] OpenedIf.cshtml)
+ IntermediateToken - (31:3,0 [7] OpenedIf.cshtml) - Html - </body>
+ CSharpCode - (38:3,7 [2] OpenedIf.cshtml)
+ IntermediateToken - (38:3,7 [2] OpenedIf.cshtml) - CSharp - \n
+ HtmlContent - (40:4,0 [7] OpenedIf.cshtml)
+ IntermediateToken - (40:4,0 [7] OpenedIf.cshtml) - Html - </html>
+ CSharpCode - (47:4,7 [0] OpenedIf.cshtml)
+ IntermediateToken - (47:4,7 [0] OpenedIf.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.mappings.txt
new file mode 100644
index 0000000000..0e07728ecc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_DesignTime.mappings.txt
@@ -0,0 +1,19 @@
+Source Location: (17:2,1 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml)
+|if (true) {
+|
+Generated Location: (716:18,1 [14] )
+|if (true) {
+|
+
+Source Location: (38:3,7 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml)
+|
+|
+Generated Location: (780:22,19 [2] )
+|
+|
+
+Source Location: (47:4,7 [0] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml)
+||
+Generated Location: (803:24,19 [0] )
+||
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.codegen.cs
new file mode 100644
index 0000000000..bbf190f222
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.codegen.cs
@@ -0,0 +1,25 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "afefc9ccf10183402eae0b9e4175393b3797a27b"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_OpenedIf_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"afefc9ccf10183402eae0b9e4175393b3797a27b", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_OpenedIf_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<html>\r\n<body>\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml"
+ if (true) {
+
+#line default
+#line hidden
+ WriteLiteral("</body>\r\n</html>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..49f293ec33
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.diagnostics.txt
@@ -0,0 +1,3 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(4,3): Error RZ1026: Encountered end tag "body" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(5,3): Error RZ1026: Encountered end tag "html" with no matching start tag. Are your start/end tags properly balanced?
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf.cshtml(3,2): Error RZ1006: The if block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.ir.txt
new file mode 100644
index 0000000000..24ee8b0ec7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/OpenedIf_Runtime.ir.txt
@@ -0,0 +1,19 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_OpenedIf_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [16] OpenedIf.cshtml)
+ IntermediateToken - (0:0,0 [6] OpenedIf.cshtml) - Html - <html>
+ IntermediateToken - (6:0,6 [2] OpenedIf.cshtml) - Html - \n
+ IntermediateToken - (8:1,0 [6] OpenedIf.cshtml) - Html - <body>
+ IntermediateToken - (14:1,6 [2] OpenedIf.cshtml) - Html - \n
+ CSharpCode - (17:2,1 [14] OpenedIf.cshtml)
+ IntermediateToken - (17:2,1 [14] OpenedIf.cshtml) - CSharp - if (true) { \n
+ HtmlContent - (31:3,0 [16] OpenedIf.cshtml)
+ IntermediateToken - (31:3,0 [7] OpenedIf.cshtml) - Html - </body>
+ IntermediateToken - (38:3,7 [2] OpenedIf.cshtml) - Html - \n
+ IntermediateToken - (40:4,0 [7] OpenedIf.cshtml) - Html - </html>
+ CSharpCode - (47:4,7 [0] OpenedIf.cshtml)
+ IntermediateToken - (47:4,7 [0] OpenedIf.cshtml) - CSharp -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml
new file mode 100644
index 0000000000..ab30e853fd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml
@@ -0,0 +1,5 @@
+@{
+/*
+int i =10;
+int j =20;
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.codegen.cs
new file mode 100644
index 0000000000..10aa94d8a5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.codegen.cs
@@ -0,0 +1,31 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ParserError_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml"
+
+/*
+int i =10;
+int j =20;
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..1a25d90e26
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml(2,1): Error RZ1001: End of file was reached before the end of the block comment. All comments started with "/*" sequence must be terminated with a matching "*/" sequence.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml(1,2): Error RZ1006: The code block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.ir.txt
new file mode 100644
index 0000000000..42fae7cec7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.ir.txt
@@ -0,0 +1,13 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ParserError_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [31] ParserError.cshtml)
+ IntermediateToken - (2:0,2 [31] ParserError.cshtml) - CSharp - \n/*\nint i =10;\nint j =20;\n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.mappings.txt
new file mode 100644
index 0000000000..4056c77df2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_DesignTime.mappings.txt
@@ -0,0 +1,13 @@
+Source Location: (2:0,2 [31] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml)
+|
+/*
+int i =10;
+int j =20;
+}|
+Generated Location: (723:18,2 [31] )
+|
+/*
+int i =10;
+int j =20;
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.codegen.cs
new file mode 100644
index 0000000000..002c92b63e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.codegen.cs
@@ -0,0 +1,27 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a94df714867cbb0e2369fe24157b5d04e2e7a9cf"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ParserError_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"a94df714867cbb0e2369fe24157b5d04e2e7a9cf", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ParserError_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml"
+
+/*
+int i =10;
+int j =20;
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..1a25d90e26
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.diagnostics.txt
@@ -0,0 +1,2 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml(2,1): Error RZ1001: End of file was reached before the end of the block comment. All comments started with "/*" sequence must be terminated with a matching "*/" sequence.
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError.cshtml(1,2): Error RZ1006: The code block is missing a closing "}" character. Make sure you have a matching "}" character for all the "{" characters within this block, and that none of the "}" characters are being interpreted as markup.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.ir.txt
new file mode 100644
index 0000000000..8f60e461b4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/ParserError_Runtime.ir.txt
@@ -0,0 +1,8 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_ParserError_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [31] ParserError.cshtml)
+ IntermediateToken - (2:0,2 [31] ParserError.cshtml) - CSharp - \n/*\nint i =10;\nint j =20;\n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml
new file mode 100644
index 0000000000..797a828688
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml
@@ -0,0 +1,23 @@
+@addTagHelper "*, TestAssembly"
+
+@{
+ var literate = "or illiterate";
+ var intDictionary = new Dictionary<string, int>
+ {
+ { "three", 3 },
+ };
+ var stringDictionary = new SortedDictionary<string, string>
+ {
+ { "name", "value" },
+ };
+}
+
+<div class="randomNonTagHelperAttribute">
+ <input type="checkbox" int-dictionary="intDictionary" string-dictionary="stringDictionary"/>
+ <input type="password" int-dictionary="intDictionary" int-prefix-garlic="37" int-prefix-grabber="42" />
+ <input type="radio"
+ int-prefix-grabber="42" int-prefix-salt="37" int-prefix-pepper="98" int-prefix-salt="8"
+ string-prefix-grabber="string" string-prefix-paprika="another string"
+ string-prefix-cumin="literate @literate?"/>
+ <input int-prefix-value="37" string-prefix-thyme="string" />
+</div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..438c533987
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,117 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PrefixedAttributeTagHelpers_DesignTime
+ {
+ private global::TestNamespace.InputTagHelper1 __TestNamespace_InputTagHelper1;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+
+ var literate = "or illiterate";
+ var intDictionary = new Dictionary<string, int>
+ {
+ { "three", 3 },
+ };
+ var stringDictionary = new SortedDictionary<string, string>
+ {
+ { "name", "value" },
+ };
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty = intDictionary;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty = __TestNamespace_InputTagHelper1.IntDictionaryProperty;
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty = stringDictionary;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty = __TestNamespace_InputTagHelper1.StringDictionaryProperty;
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty = intDictionary;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty = __TestNamespace_InputTagHelper1.IntDictionaryProperty;
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"] = 37;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["garlic"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"];
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper1.IntProperty = 42;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.IntProperty;
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntProperty = 42;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.IntProperty;
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"] = 37;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["salt"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"];
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ __TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"] = 98;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["pepper"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"];
+ __TestNamespace_InputTagHelper1.StringProperty = "string";
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.StringProperty;
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["paprika"] = "another string";
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["paprika"] = __TestNamespace_InputTagHelper1.StringDictionaryProperty["paprika"];
+#line 21 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ __o = literate;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["cumin"] = string.Empty;
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["cumin"] = __TestNamespace_InputTagHelper1.StringDictionaryProperty["cumin"];
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["value"] = 37;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["value"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"];
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["thyme"] = "string";
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["thyme"] = __TestNamespace_InputTagHelper1.StringDictionaryProperty["thyme"];
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..add0db7eff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,136 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PrefixedAttributeTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper1 - __TestNamespace_InputTagHelper1
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] PrefixedAttributeTagHelpers.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (31:0,31 [4] PrefixedAttributeTagHelpers.cshtml) - Html - \n\n
+ CSharpCode - (37:2,2 [242] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (37:2,2 [242] PrefixedAttributeTagHelpers.cshtml) - CSharp - \n var literate = "or illiterate";\n var intDictionary = new Dictionary<string, int>\n {\n { "three", 3 },\n };\n var stringDictionary = new SortedDictionary<string, string>\n {\n { "name", "value" },\n };\n
+ HtmlContent - (282:13,0 [49] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (282:13,0 [2] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (284:14,0 [4] PrefixedAttributeTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (288:14,4 [36] PrefixedAttributeTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (324:14,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html - >
+ IntermediateToken - (325:14,41 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (331:15,4 [92] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (344:15,17 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (344:15,17 [8] PrefixedAttributeTagHelpers.cshtml) - Html - checkbox
+ DefaultTagHelperProperty - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - string-dictionary - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - CSharp - stringDictionary
+ DefaultTagHelperProperty - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - string-dictionary - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - CSharp - stringDictionary
+ DefaultTagHelperExecute -
+ HtmlContent - (423:15,96 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (423:15,96 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (429:16,4 [103] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (442:16,17 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (442:16,17 [8] PrefixedAttributeTagHelpers.cshtml) - Html - password
+ DefaultTagHelperProperty - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-garlic - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-garlic - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper1.IntProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperExecute -
+ HtmlContent - (532:16,107 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (532:16,107 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (538:17,4 [257] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (551:17,17 [5] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (551:17,17 [5] PrefixedAttributeTagHelpers.cshtml) - Html - radio
+ DefaultTagHelperProperty - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper1.IntProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-salt - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-salt - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-pepper - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 98
+ DefaultTagHelperProperty - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-pepper - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 98
+ DefaultTagHelperHtmlAttribute - - int-prefix-salt - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (655:18,96 [1] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (655:18,96 [1] PrefixedAttributeTagHelpers.cshtml) - Html - 8
+ DefaultTagHelperProperty - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - string-prefix-grabber - string TestNamespace.InputTagHelper1.StringProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - Html - string
+ DefaultTagHelperProperty - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - string-prefix-grabber - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - Html - string
+ DefaultTagHelperProperty - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - string-prefix-paprika - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - Html - another string
+ DefaultTagHelperProperty - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - string-prefix-paprika - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - Html - another string
+ DefaultTagHelperProperty - (773:20,32 [19] PrefixedAttributeTagHelpers.cshtml) - string-prefix-cumin - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (773:20,32 [9] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (773:20,32 [8] PrefixedAttributeTagHelpers.cshtml) - Html - literate
+ IntermediateToken - (781:20,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml) - CSharp - literate
+ HtmlContent - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml) - Html - ?
+ DefaultTagHelperProperty - (773:20,32 [19] PrefixedAttributeTagHelpers.cshtml) - string-prefix-cumin - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (773:20,32 [9] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (773:20,32 [8] PrefixedAttributeTagHelpers.cshtml) - Html - literate
+ IntermediateToken - (781:20,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml) - CSharp - literate
+ HtmlContent - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml) - Html - ?
+ DefaultTagHelperExecute -
+ HtmlContent - (795:20,54 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (795:20,54 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (801:21,4 [60] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-value - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-value - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - string-prefix-thyme - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - Html - string
+ DefaultTagHelperProperty - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - string-prefix-thyme - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - Html - string
+ DefaultTagHelperExecute -
+ HtmlContent - (861:21,64 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (861:21,64 [2] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (863:22,0 [6] PrefixedAttributeTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..2f22a4d206
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,80 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|"*, TestAssembly"|
+Generated Location: (609:12,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (37:2,2 [242] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|
+ var literate = "or illiterate";
+ var intDictionary = new Dictionary<string, int>
+ {
+ { "three", 3 },
+ };
+ var stringDictionary = new SortedDictionary<string, string>
+ {
+ { "name", "value" },
+ };
+|
+Generated Location: (1048:24,2 [242] )
+|
+ var literate = "or illiterate";
+ var intDictionary = new Dictionary<string, int>
+ {
+ { "three", 3 },
+ };
+ var stringDictionary = new SortedDictionary<string, string>
+ {
+ { "name", "value" },
+ };
+|
+
+Source Location: (370:15,43 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|intDictionary|
+Generated Location: (1691:40,56 [13] )
+|intDictionary|
+
+Source Location: (404:15,77 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|stringDictionary|
+Generated Location: (2043:46,77 [16] )
+|stringDictionary|
+
+Source Location: (468:16,43 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|intDictionary|
+Generated Location: (2593:54,56 [13] )
+|intDictionary|
+
+Source Location: (502:16,77 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|37|
+Generated Location: (2945:60,77 [2] )
+|37|
+
+Source Location: (526:16,101 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|42|
+Generated Location: (3330:66,101 [2] )
+|42|
+
+Source Location: (590:18,31 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|42|
+Generated Location: (3851:74,46 [2] )
+|42|
+
+Source Location: (611:18,52 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|37|
+Generated Location: (4180:80,64 [2] )
+|37|
+
+Source Location: (634:18,75 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|98|
+Generated Location: (4535:86,75 [2] )
+|98|
+
+Source Location: (783:20,42 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|literate|
+Generated Location: (5317:96,42 [8] )
+|literate|
+
+Source Location: (826:21,29 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml)
+|37|
+Generated Location: (5981:105,65 [2] )
+|37|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..8a6d41c750
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,260 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "fc1a85ca24bc6ae7170b67e2d8371cede965879e"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PrefixedAttributeTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"fc1a85ca24bc6ae7170b67e2d8371cede965879e", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PrefixedAttributeTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("checkbox"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("password"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("radio"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("int-prefix-salt", new global::Microsoft.AspNetCore.Html.HtmlString("8"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("string-prefix-grabber", "string", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("string-prefix-paprika", "another string", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("string-prefix-thyme", "string", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.InputTagHelper1 __TestNamespace_InputTagHelper1;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+
+ var literate = "or illiterate";
+ var intDictionary = new Dictionary<string, int>
+ {
+ { "three", 3 },
+ };
+ var stringDictionary = new SortedDictionary<string, string>
+ {
+ { "name", "value" },
+ };
+
+#line default
+#line hidden
+ WriteLiteral("\r\n<div class=\"randomNonTagHelperAttribute\">\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper1);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty = intDictionary;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-dictionary", __TestNamespace_InputTagHelper1.IntDictionaryProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty = __TestNamespace_InputTagHelper1.IntDictionaryProperty;
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.StringDictionaryProperty = stringDictionary;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("string-dictionary", __TestNamespace_InputTagHelper1.StringDictionaryProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty = __TestNamespace_InputTagHelper1.StringDictionaryProperty;
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper1);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty = intDictionary;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-dictionary", __TestNamespace_InputTagHelper1.IntDictionaryProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty = __TestNamespace_InputTagHelper1.IntDictionaryProperty;
+ if (__TestNamespace_InputTagHelper1.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-garlic", "TestNamespace.InputTagHelper1", "IntDictionaryProperty"));
+ }
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"] = 37;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-garlic", __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ if (__TestNamespace_InputTagHelper2.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-garlic", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["garlic"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"];
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntProperty = 42;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-grabber", __TestNamespace_InputTagHelper1.IntProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.IntProperty;
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper1);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntProperty = 42;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-grabber", __TestNamespace_InputTagHelper1.IntProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ if (__TestNamespace_InputTagHelper2.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-grabber", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.IntProperty;
+ if (__TestNamespace_InputTagHelper1.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-salt", "TestNamespace.InputTagHelper1", "IntDictionaryProperty"));
+ }
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"] = 37;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-salt", __TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["salt"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"];
+#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"] = 98;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-pepper", __TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["pepper"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"];
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ __TestNamespace_InputTagHelper1.StringProperty = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ if (__TestNamespace_InputTagHelper2.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-grabber", "TestNamespace.InputTagHelper2", "StringDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["grabber"] = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-paprika", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["paprika"] = (string)__tagHelperAttribute_5.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["paprika"] = (string)__tagHelperAttribute_5.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
+ if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-cumin", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
+ }
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("literate ");
+#line 21 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+ WriteLiteral(literate);
+
+#line default
+#line hidden
+ WriteLiteral("?");
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["cumin"] = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("string-prefix-cumin", __TestNamespace_InputTagHelper1.StringDictionaryProperty["cumin"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ if (__TestNamespace_InputTagHelper2.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-cumin", "TestNamespace.InputTagHelper2", "StringDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["cumin"] = __TestNamespace_InputTagHelper1.StringDictionaryProperty["cumin"];
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper1 = CreateTagHelper<global::TestNamespace.InputTagHelper1>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper1);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ if (__TestNamespace_InputTagHelper1.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-value", "TestNamespace.InputTagHelper1", "IntDictionaryProperty"));
+ }
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
+__TestNamespace_InputTagHelper1.IntDictionaryProperty["value"] = 37;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-value", __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ if (__TestNamespace_InputTagHelper2.IntDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-value", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.IntDictionaryProperty["value"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"];
+ if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-thyme", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper1.StringDictionaryProperty["thyme"] = (string)__tagHelperAttribute_6.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
+ if (__TestNamespace_InputTagHelper2.StringDictionaryProperty == null)
+ {
+ throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-thyme", "TestNamespace.InputTagHelper2", "StringDictionaryProperty"));
+ }
+ __TestNamespace_InputTagHelper2.StringDictionaryProperty["thyme"] = (string)__tagHelperAttribute_6.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</div>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..892245a292
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers_Runtime.ir.txt
@@ -0,0 +1,117 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_PrefixedAttributeTagHelpers_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - password - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - type - radio - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - int-prefix-salt - 8 - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_4 - string-prefix-grabber - string - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_5 - string-prefix-paprika - another string - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_6 - string-prefix-thyme - string - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper1 - __TestNamespace_InputTagHelper1
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (33:1,0 [2] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ CSharpCode - (37:2,2 [242] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (37:2,2 [242] PrefixedAttributeTagHelpers.cshtml) - CSharp - \n var literate = "or illiterate";\n var intDictionary = new Dictionary<string, int>\n {\n { "three", 3 },\n };\n var stringDictionary = new SortedDictionary<string, string>\n {\n { "name", "value" },\n };\n
+ HtmlContent - (282:13,0 [49] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (282:13,0 [2] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (284:14,0 [4] PrefixedAttributeTagHelpers.cshtml) - Html - <div
+ IntermediateToken - (288:14,4 [36] PrefixedAttributeTagHelpers.cshtml) - Html - class="randomNonTagHelperAttribute"
+ IntermediateToken - (324:14,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html - >
+ IntermediateToken - (325:14,41 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (331:15,4 [92] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (370:15,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - string-dictionary - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - CSharp - stringDictionary
+ DefaultTagHelperProperty - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - string-dictionary - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (404:15,77 [16] PrefixedAttributeTagHelpers.cshtml) - CSharp - stringDictionary
+ DefaultTagHelperExecute -
+ HtmlContent - (423:15,96 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (423:15,96 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (429:16,4 [103] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperProperty - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - int-dictionary - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (468:16,43 [13] PrefixedAttributeTagHelpers.cshtml) - CSharp - intDictionary
+ DefaultTagHelperProperty - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-garlic - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-garlic - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (502:16,77 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper1.IntProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (526:16,101 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperExecute -
+ HtmlContent - (532:16,107 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (532:16,107 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (538:17,4 [257] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperProperty - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper1.IntProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-grabber - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (590:18,31 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 42
+ DefaultTagHelperProperty - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-salt - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-salt - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (611:18,52 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-pepper - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 98
+ DefaultTagHelperProperty - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-pepper - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (634:18,75 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 98
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ PreallocatedTagHelperProperty - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_4 - string-prefix-grabber - StringProperty
+ PreallocatedTagHelperProperty - (693:19,34 [6] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_4 - string-prefix-grabber - StringDictionaryProperty
+ PreallocatedTagHelperProperty - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_5 - string-prefix-paprika - StringDictionaryProperty
+ PreallocatedTagHelperProperty - (724:19,65 [14] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_5 - string-prefix-paprika - StringDictionaryProperty
+ DefaultTagHelperProperty - (773:20,32 [19] PrefixedAttributeTagHelpers.cshtml) - string-prefix-cumin - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper1.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (773:20,32 [9] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (773:20,32 [8] PrefixedAttributeTagHelpers.cshtml) - Html - literate
+ IntermediateToken - (781:20,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml) - CSharp - literate
+ HtmlContent - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml) - Html - ?
+ DefaultTagHelperProperty - (773:20,32 [19] PrefixedAttributeTagHelpers.cshtml) - string-prefix-cumin - Namespace.DictionaryWithoutParameterlessConstructor<string, string> TestNamespace.InputTagHelper2.StringDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (773:20,32 [9] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (773:20,32 [8] PrefixedAttributeTagHelpers.cshtml) - Html - literate
+ IntermediateToken - (781:20,40 [1] PrefixedAttributeTagHelpers.cshtml) - Html -
+ CSharpExpression - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (783:20,42 [8] PrefixedAttributeTagHelpers.cshtml) - CSharp - literate
+ HtmlContent - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (791:20,50 [1] PrefixedAttributeTagHelpers.cshtml) - Html - ?
+ DefaultTagHelperExecute -
+ HtmlContent - (795:20,54 [6] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (795:20,54 [6] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ TagHelper - (801:21,4 [60] PrefixedAttributeTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper1
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-value - System.Collections.Generic.IDictionary<string, int> TestNamespace.InputTagHelper1.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ DefaultTagHelperProperty - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - int-prefix-value - int TestNamespace.InputTagHelper2.IntDictionaryProperty - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (826:21,29 [2] PrefixedAttributeTagHelpers.cshtml) - CSharp - 37
+ PreallocatedTagHelperProperty - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_6 - string-prefix-thyme - StringDictionaryProperty
+ PreallocatedTagHelperProperty - (851:21,54 [6] PrefixedAttributeTagHelpers.cshtml) - __tagHelperAttribute_6 - string-prefix-thyme - StringDictionaryProperty
+ DefaultTagHelperExecute -
+ HtmlContent - (861:21,64 [8] PrefixedAttributeTagHelpers.cshtml)
+ IntermediateToken - (861:21,64 [2] PrefixedAttributeTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (863:22,0 [6] PrefixedAttributeTagHelpers.cshtml) - Html - </div>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml
new file mode 100644
index 0000000000..bd4820f914
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml
@@ -0,0 +1,15 @@
+@*This is not going to be rendered*@
+<p>This should @* not *@ be shown</p>
+
+@{
+ @* throw new Exception("Oh no!") *@
+ Exception foo = @* new Exception("Oh no!") *@ null;
+ if(foo != null) {
+ throw foo;
+ }
+}
+
+@{ var bar = "@* bar *@"; }
+<p>But this should show the comment syntax: @bar</p>
+
+@(a@**@b)
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.codegen.cs
new file mode 100644
index 0000000000..a21ac99866
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.codegen.cs
@@ -0,0 +1,53 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+
+ Exception foo =
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ null;
+ if(foo != null) {
+ throw foo;
+ }
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ var bar = "@* bar *@";
+
+#line default
+#line hidden
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ __o = bar;
+
+#line default
+#line hidden
+#line 15 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+__o = ab;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt
new file mode 100644
index 0000000000..e75591ec2d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.ir.txt
@@ -0,0 +1,42 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (36:0,36 [17] RazorComments.cshtml)
+ IntermediateToken - (36:0,36 [2] RazorComments.cshtml) - Html - \n
+ IntermediateToken - (38:1,0 [3] RazorComments.cshtml) - Html - <p>
+ IntermediateToken - (41:1,3 [12] RazorComments.cshtml) - Html - This should
+ HtmlContent - (62:1,24 [17] RazorComments.cshtml)
+ IntermediateToken - (62:1,24 [9] RazorComments.cshtml) - Html - be shown
+ IntermediateToken - (71:1,33 [4] RazorComments.cshtml) - Html - </p>
+ IntermediateToken - (75:1,37 [4] RazorComments.cshtml) - Html - \n\n
+ CSharpCode - (81:3,2 [6] RazorComments.cshtml)
+ IntermediateToken - (81:3,2 [6] RazorComments.cshtml) - CSharp - \n
+ CSharpCode - (122:4,39 [22] RazorComments.cshtml)
+ IntermediateToken - (122:4,39 [22] RazorComments.cshtml) - CSharp - \n Exception foo =
+ CSharpCode - (173:5,49 [58] RazorComments.cshtml)
+ IntermediateToken - (173:5,49 [58] RazorComments.cshtml) - CSharp - null;\n if(foo != null) {\n throw foo;\n }\n
+ HtmlContent - (234:10,0 [2] RazorComments.cshtml)
+ IntermediateToken - (234:10,0 [2] RazorComments.cshtml) - Html - \n
+ CSharpCode - (238:11,2 [24] RazorComments.cshtml)
+ IntermediateToken - (238:11,2 [24] RazorComments.cshtml) - CSharp - var bar = "@* bar *@";
+ HtmlContent - (265:12,0 [44] RazorComments.cshtml)
+ IntermediateToken - (265:12,0 [3] RazorComments.cshtml) - Html - <p>
+ IntermediateToken - (268:12,3 [41] RazorComments.cshtml) - Html - But this should show the comment syntax:
+ CSharpExpression - (310:12,45 [3] RazorComments.cshtml)
+ IntermediateToken - (310:12,45 [3] RazorComments.cshtml) - CSharp - bar
+ HtmlContent - (313:12,48 [8] RazorComments.cshtml)
+ IntermediateToken - (313:12,48 [4] RazorComments.cshtml) - Html - </p>
+ IntermediateToken - (317:12,52 [4] RazorComments.cshtml) - Html - \n\n
+ CSharpExpression - (323:14,2 [2] RazorComments.cshtml)
+ IntermediateToken - (323:14,2 [1] RazorComments.cshtml) - CSharp - a
+ IntermediateToken - (328:14,7 [1] RazorComments.cshtml) - CSharp - b
+ HtmlContent - (330:14,9 [2] RazorComments.cshtml)
+ IntermediateToken - (330:14,9 [2] RazorComments.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.mappings.txt
new file mode 100644
index 0000000000..3278641353
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_DesignTime.mappings.txt
@@ -0,0 +1,47 @@
+Source Location: (81:3,2 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+|
+ |
+Generated Location: (650:17,14 [6] )
+|
+ |
+
+Source Location: (122:4,39 [22] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+|
+ Exception foo = |
+Generated Location: (786:20,39 [22] )
+|
+ Exception foo = |
+
+Source Location: (173:5,49 [58] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+| null;
+ if(foo != null) {
+ throw foo;
+ }
+|
+Generated Location: (979:26,49 [58] )
+| null;
+ if(foo != null) {
+ throw foo;
+ }
+|
+
+Source Location: (238:11,2 [24] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+| var bar = "@* bar *@"; |
+Generated Location: (1160:34,2 [24] )
+| var bar = "@* bar *@"; |
+
+Source Location: (310:12,45 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+|bar|
+Generated Location: (1352:39,45 [3] )
+|bar|
+
+Source Location: (323:14,2 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+|a|
+Generated Location: (1485:44,6 [1] )
+|a|
+
+Source Location: (328:14,7 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml)
+|b|
+Generated Location: (1486:44,7 [1] )
+|b|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs
new file mode 100644
index 0000000000..d9b27a45c7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.codegen.cs
@@ -0,0 +1,53 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "051345e2cc0313fea445db2f6cf48fe28b0b4edf"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"051345e2cc0313fea445db2f6cf48fe28b0b4edf", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<p>This should ");
+ WriteLiteral(" be shown</p>\r\n\r\n");
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+
+ Exception foo =
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ null;
+ if(foo != null) {
+ throw foo;
+ }
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ var bar = "@* bar *@";
+
+#line default
+#line hidden
+ WriteLiteral("<p>But this should show the comment syntax: ");
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+ Write(bar);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n\r\n");
+#line 15 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments.cshtml"
+Write(ab);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt
new file mode 100644
index 0000000000..e05218677f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RazorComments_Runtime.ir.txt
@@ -0,0 +1,37 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RazorComments_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (36:0,36 [17] RazorComments.cshtml)
+ IntermediateToken - (36:0,36 [2] RazorComments.cshtml) - Html - \n
+ IntermediateToken - (38:1,0 [3] RazorComments.cshtml) - Html - <p>
+ IntermediateToken - (41:1,3 [12] RazorComments.cshtml) - Html - This should
+ HtmlContent - (62:1,24 [17] RazorComments.cshtml)
+ IntermediateToken - (62:1,24 [9] RazorComments.cshtml) - Html - be shown
+ IntermediateToken - (71:1,33 [4] RazorComments.cshtml) - Html - </p>
+ IntermediateToken - (75:1,37 [4] RazorComments.cshtml) - Html - \n\n
+ CSharpCode - (81:3,2 [6] RazorComments.cshtml)
+ IntermediateToken - (81:3,2 [6] RazorComments.cshtml) - CSharp - \n
+ CSharpCode - (122:4,39 [22] RazorComments.cshtml)
+ IntermediateToken - (122:4,39 [22] RazorComments.cshtml) - CSharp - \n Exception foo =
+ CSharpCode - (173:5,49 [58] RazorComments.cshtml)
+ IntermediateToken - (173:5,49 [58] RazorComments.cshtml) - CSharp - null;\n if(foo != null) {\n throw foo;\n }\n
+ HtmlContent - (234:10,0 [2] RazorComments.cshtml)
+ IntermediateToken - (234:10,0 [2] RazorComments.cshtml) - Html - \n
+ CSharpCode - (238:11,2 [24] RazorComments.cshtml)
+ IntermediateToken - (238:11,2 [24] RazorComments.cshtml) - CSharp - var bar = "@* bar *@";
+ HtmlContent - (265:12,0 [44] RazorComments.cshtml)
+ IntermediateToken - (265:12,0 [3] RazorComments.cshtml) - Html - <p>
+ IntermediateToken - (268:12,3 [41] RazorComments.cshtml) - Html - But this should show the comment syntax:
+ CSharpExpression - (310:12,45 [3] RazorComments.cshtml)
+ IntermediateToken - (310:12,45 [3] RazorComments.cshtml) - CSharp - bar
+ HtmlContent - (313:12,48 [8] RazorComments.cshtml)
+ IntermediateToken - (313:12,48 [4] RazorComments.cshtml) - Html - </p>
+ IntermediateToken - (317:12,52 [4] RazorComments.cshtml) - Html - \n\n
+ CSharpExpression - (323:14,2 [2] RazorComments.cshtml)
+ IntermediateToken - (323:14,2 [1] RazorComments.cshtml) - CSharp - a
+ IntermediateToken - (328:14,7 [1] RazorComments.cshtml) - CSharp - b
+ HtmlContent - (330:14,9 [2] RazorComments.cshtml)
+ IntermediateToken - (330:14,9 [2] RazorComments.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective.cshtml
new file mode 100644
index 0000000000..a8cd525a3d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective.cshtml
@@ -0,0 +1 @@
+@removeTagHelper *, TestAssembly
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.codegen.cs
new file mode 100644
index 0000000000..860fed746d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.codegen.cs
@@ -0,0 +1,26 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RemoveTagHelperDirective_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.ir.txt
new file mode 100644
index 0000000000..8a37436277
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.ir.txt
@@ -0,0 +1,14 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_RemoveTagHelperDirective_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (17:0,17 [15] RemoveTagHelperDirective.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (32:0,32 [2] RemoveTagHelperDirective.cshtml)
+ IntermediateToken - (32:0,32 [2] RemoveTagHelperDirective.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.mappings.txt
new file mode 100644
index 0000000000..709b86af82
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (17:0,17 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/RemoveTagHelperDirective.cshtml)
+|*, TestAssembly|
+Generated Location: (431:10,38 [15] )
+|*, TestAssembly|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml
new file mode 100644
index 0000000000..952461002f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml
@@ -0,0 +1,17 @@
+@{
+ Layout = "_SectionTestLayout.cshtml"
+}
+
+<div>This is in the Body>
+
+@section Section2 {
+ <div class="some @thing">This is in Section 2</div>
+}
+
+@section Section1 {
+ <div>This is in Section 1</div>
+}
+
+@section NestedDelegates {
+ @{ Func<dynamic, object> f = @<span>@item</span>; }
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs
new file mode 100644
index 0000000000..556cf5e489
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.codegen.cs
@@ -0,0 +1,72 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object Section2 = null;
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object Section1 = null;
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object NestedDelegates = null;
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+
+ Layout = "_SectionTestLayout.cshtml"
+
+#line default
+#line hidden
+ DefineSection("Section2", async(__razor_section_writer) => {
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ __o = thing;
+
+#line default
+#line hidden
+ }
+ );
+ DefineSection("Section1", async(__razor_section_writer) => {
+ }
+ );
+ DefineSection("NestedDelegates", async(__razor_section_writer) => {
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ Func<dynamic, object> f =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+ }
+ )
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ ;
+
+#line default
+#line hidden
+ }
+ );
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt
new file mode 100644
index 0000000000..99f9d77261
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.ir.txt
@@ -0,0 +1,59 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (89:6,9 [8] Sections.cshtml) - Section2
+ DirectiveToken - (172:10,9 [8] Sections.cshtml) - Section1
+ DirectiveToken - (235:14,9 [15] Sections.cshtml) - NestedDelegates
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [44] Sections.cshtml)
+ IntermediateToken - (2:0,2 [44] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml"\n
+ HtmlContent - (49:3,0 [31] Sections.cshtml)
+ IntermediateToken - (49:3,0 [2] Sections.cshtml) - Html - \n
+ IntermediateToken - (51:4,0 [5] Sections.cshtml) - Html - <div>
+ IntermediateToken - (56:4,5 [24] Sections.cshtml) - Html - This is in the Body>\n\n
+ Section - - Section2
+ HtmlContent - (99:6,19 [10] Sections.cshtml)
+ IntermediateToken - (99:6,19 [6] Sections.cshtml) - Html - \n
+ IntermediateToken - (105:7,4 [4] Sections.cshtml) - Html - <div
+ HtmlAttribute - (109:7,8 [20] Sections.cshtml) - class=" - "
+ HtmlAttributeValue - (117:7,16 [4] Sections.cshtml) -
+ IntermediateToken - (117:7,16 [4] Sections.cshtml) - Html - some
+ CSharpExpressionAttributeValue - (121:7,20 [7] Sections.cshtml) -
+ IntermediateToken - (123:7,22 [5] Sections.cshtml) - CSharp - thing
+ HtmlContent - (129:7,28 [29] Sections.cshtml)
+ IntermediateToken - (129:7,28 [1] Sections.cshtml) - Html - >
+ IntermediateToken - (130:7,29 [20] Sections.cshtml) - Html - This is in Section 2
+ IntermediateToken - (150:7,49 [6] Sections.cshtml) - Html - </div>
+ IntermediateToken - (156:7,55 [2] Sections.cshtml) - Html - \n
+ HtmlContent - (159:8,1 [4] Sections.cshtml)
+ IntermediateToken - (159:8,1 [4] Sections.cshtml) - Html - \n\n
+ Section - - Section1
+ HtmlContent - (182:10,19 [39] Sections.cshtml)
+ IntermediateToken - (182:10,19 [6] Sections.cshtml) - Html - \n
+ IntermediateToken - (188:11,4 [5] Sections.cshtml) - Html - <div>
+ IntermediateToken - (193:11,9 [20] Sections.cshtml) - Html - This is in Section 1
+ IntermediateToken - (213:11,29 [6] Sections.cshtml) - Html - </div>
+ IntermediateToken - (219:11,35 [2] Sections.cshtml) - Html - \n
+ HtmlContent - (222:12,1 [4] Sections.cshtml)
+ IntermediateToken - (222:12,1 [4] Sections.cshtml) - Html - \n\n
+ Section - - NestedDelegates
+ HtmlContent - (252:14,26 [6] Sections.cshtml)
+ IntermediateToken - (252:14,26 [6] Sections.cshtml) - Html - \n
+ CSharpCode - (260:15,6 [27] Sections.cshtml)
+ IntermediateToken - (260:15,6 [27] Sections.cshtml) - CSharp - Func<dynamic, object> f =
+ Template - (288:15,34 [17] Sections.cshtml)
+ HtmlContent - (288:15,34 [6] Sections.cshtml)
+ IntermediateToken - (288:15,34 [6] Sections.cshtml) - Html - <span>
+ CSharpExpression - (295:15,41 [4] Sections.cshtml)
+ IntermediateToken - (295:15,41 [4] Sections.cshtml) - CSharp - item
+ HtmlContent - (299:15,45 [7] Sections.cshtml)
+ IntermediateToken - (299:15,45 [7] Sections.cshtml) - Html - </span>
+ CSharpCode - (306:15,52 [2] Sections.cshtml)
+ IntermediateToken - (306:15,52 [2] Sections.cshtml) - CSharp - ;
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt
new file mode 100644
index 0000000000..f6aedef836
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_DesignTime.mappings.txt
@@ -0,0 +1,44 @@
+Source Location: (89:6,9 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|Section2|
+Generated Location: (399:10,22 [8] )
+|Section2|
+
+Source Location: (172:10,9 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|Section1|
+Generated Location: (499:14,22 [8] )
+|Section1|
+
+Source Location: (235:14,9 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|NestedDelegates|
+Generated Location: (599:18,22 [15] )
+|NestedDelegates|
+
+Source Location: (2:0,2 [44] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|
+ Layout = "_SectionTestLayout.cshtml"
+|
+Generated Location: (1024:30,2 [44] )
+|
+ Layout = "_SectionTestLayout.cshtml"
+|
+
+Source Location: (123:7,22 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|thing|
+Generated Location: (1279:37,22 [5] )
+|thing|
+
+Source Location: (260:15,6 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+| Func<dynamic, object> f = |
+Generated Location: (1626:48,6 [27] )
+| Func<dynamic, object> f = |
+
+Source Location: (295:15,41 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|item|
+Generated Location: (1886:54,41 [4] )
+|item|
+
+Source Location: (306:15,52 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml)
+|; |
+Generated Location: (2099:61,52 [2] )
+|; |
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs
new file mode 100644
index 0000000000..3e6af4799b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.codegen.cs
@@ -0,0 +1,70 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "2c1cd9bdf77c65fcccd7f5b86be5746c1381be0e"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"2c1cd9bdf77c65fcccd7f5b86be5746c1381be0e", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+
+ Layout = "_SectionTestLayout.cshtml"
+
+#line default
+#line hidden
+ WriteLiteral("\r\n<div>This is in the Body>\r\n\r\n");
+ DefineSection("Section2", async() => {
+ WriteLiteral("\r\n <div");
+ BeginWriteAttribute("class", " class=\"", 109, "\"", 128, 2);
+ WriteAttributeValue("", 117, "some", 117, 4, true);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+WriteAttributeValue(" ", 121, thing, 122, 6, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(">This is in Section 2</div>\r\n");
+ }
+ );
+ WriteLiteral("\r\n");
+ DefineSection("Section1", async() => {
+ WriteLiteral("\r\n <div>This is in Section 1</div>\r\n");
+ }
+ );
+ WriteLiteral("\r\n");
+ DefineSection("NestedDelegates", async() => {
+ WriteLiteral("\r\n");
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ Func<dynamic, object> f =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("<span>");
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral("</span>");
+ PopWriter();
+ }
+ )
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections.cshtml"
+ ;
+
+#line default
+#line hidden
+ }
+ );
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt
new file mode 100644
index 0000000000..be452577fe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Sections_Runtime.ir.txt
@@ -0,0 +1,53 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Sections_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [44] Sections.cshtml)
+ IntermediateToken - (2:0,2 [44] Sections.cshtml) - CSharp - \n Layout = "_SectionTestLayout.cshtml"\n
+ HtmlContent - (49:3,0 [31] Sections.cshtml)
+ IntermediateToken - (49:3,0 [2] Sections.cshtml) - Html - \n
+ IntermediateToken - (51:4,0 [5] Sections.cshtml) - Html - <div>
+ IntermediateToken - (56:4,5 [24] Sections.cshtml) - Html - This is in the Body>\n\n
+ Section - - Section2
+ HtmlContent - (99:6,19 [10] Sections.cshtml)
+ IntermediateToken - (99:6,19 [6] Sections.cshtml) - Html - \n
+ IntermediateToken - (105:7,4 [4] Sections.cshtml) - Html - <div
+ HtmlAttribute - (109:7,8 [20] Sections.cshtml) - class=" - "
+ HtmlAttributeValue - (117:7,16 [4] Sections.cshtml) -
+ IntermediateToken - (117:7,16 [4] Sections.cshtml) - Html - some
+ CSharpExpressionAttributeValue - (121:7,20 [7] Sections.cshtml) -
+ IntermediateToken - (123:7,22 [5] Sections.cshtml) - CSharp - thing
+ HtmlContent - (129:7,28 [29] Sections.cshtml)
+ IntermediateToken - (129:7,28 [1] Sections.cshtml) - Html - >
+ IntermediateToken - (130:7,29 [20] Sections.cshtml) - Html - This is in Section 2
+ IntermediateToken - (150:7,49 [6] Sections.cshtml) - Html - </div>
+ IntermediateToken - (156:7,55 [2] Sections.cshtml) - Html - \n
+ HtmlContent - (161:9,0 [2] Sections.cshtml)
+ IntermediateToken - (161:9,0 [2] Sections.cshtml) - Html - \n
+ Section - - Section1
+ HtmlContent - (182:10,19 [39] Sections.cshtml)
+ IntermediateToken - (182:10,19 [6] Sections.cshtml) - Html - \n
+ IntermediateToken - (188:11,4 [5] Sections.cshtml) - Html - <div>
+ IntermediateToken - (193:11,9 [20] Sections.cshtml) - Html - This is in Section 1
+ IntermediateToken - (213:11,29 [6] Sections.cshtml) - Html - </div>
+ IntermediateToken - (219:11,35 [2] Sections.cshtml) - Html - \n
+ HtmlContent - (224:13,0 [2] Sections.cshtml)
+ IntermediateToken - (224:13,0 [2] Sections.cshtml) - Html - \n
+ Section - - NestedDelegates
+ HtmlContent - (252:14,26 [2] Sections.cshtml)
+ IntermediateToken - (252:14,26 [2] Sections.cshtml) - Html - \n
+ CSharpCode - (254:15,0 [4] Sections.cshtml)
+ IntermediateToken - (254:15,0 [4] Sections.cshtml) - CSharp -
+ CSharpCode - (260:15,6 [27] Sections.cshtml)
+ IntermediateToken - (260:15,6 [27] Sections.cshtml) - CSharp - Func<dynamic, object> f =
+ Template - (288:15,34 [17] Sections.cshtml)
+ HtmlContent - (288:15,34 [6] Sections.cshtml)
+ IntermediateToken - (288:15,34 [6] Sections.cshtml) - Html - <span>
+ CSharpExpression - (295:15,41 [4] Sections.cshtml)
+ IntermediateToken - (295:15,41 [4] Sections.cshtml) - CSharp - item
+ HtmlContent - (299:15,45 [7] Sections.cshtml)
+ IntermediateToken - (299:15,45 [7] Sections.cshtml) - Html - </span>
+ CSharpCode - (306:15,52 [2] Sections.cshtml)
+ IntermediateToken - (306:15,52 [2] Sections.cshtml) - CSharp - ;
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml
new file mode 100644
index 0000000000..bd4ce8107a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml
@@ -0,0 +1,5 @@
+@addTagHelper *, TestAssembly
+<p>Hola</p>
+<form>
+ <input value='Hello' type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.codegen.cs
new file mode 100644
index 0000000000..3cbb810d65
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.codegen.cs
@@ -0,0 +1,29 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleTagHelpers_DesignTime
+ {
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __InputTagHelper.FooProp = "Hello";
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.ir.txt
new file mode 100644
index 0000000000..6625ddd86c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.ir.txt
@@ -0,0 +1,35 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleTagHelpers_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] SimpleTagHelpers.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [27] SimpleTagHelpers.cshtml)
+ IntermediateToken - (29:0,29 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (31:1,0 [3] SimpleTagHelpers.cshtml) - Html - <p>
+ IntermediateToken - (34:1,3 [4] SimpleTagHelpers.cshtml) - Html - Hola
+ IntermediateToken - (38:1,7 [4] SimpleTagHelpers.cshtml) - Html - </p>
+ IntermediateToken - (42:1,11 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (44:2,0 [6] SimpleTagHelpers.cshtml) - Html - <form>
+ IntermediateToken - (50:2,6 [6] SimpleTagHelpers.cshtml) - Html - \n
+ TagHelper - (56:3,4 [35] SimpleTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (70:3,18 [5] SimpleTagHelpers.cshtml) - value - string InputTagHelper.FooProp - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (70:3,18 [5] SimpleTagHelpers.cshtml)
+ IntermediateToken - (70:3,18 [5] SimpleTagHelpers.cshtml) - Html - Hello
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (83:3,31 [4] SimpleTagHelpers.cshtml)
+ IntermediateToken - (83:3,31 [4] SimpleTagHelpers.cshtml) - Html - text
+ DefaultTagHelperExecute -
+ HtmlContent - (91:3,39 [9] SimpleTagHelpers.cshtml)
+ IntermediateToken - (91:3,39 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (93:4,0 [7] SimpleTagHelpers.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.mappings.txt
new file mode 100644
index 0000000000..79472b01be
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_DesignTime.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml)
+|*, TestAssembly|
+Generated Location: (481:11,38 [15] )
+|*, TestAssembly|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.codegen.cs
new file mode 100644
index 0000000000..4d5cd87159
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.codegen.cs
@@ -0,0 +1,56 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "e2cfd373c979f0844c2fd0ff78d289027202a932"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleTagHelpers_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"e2cfd373c979f0844c2fd0ff78d289027202a932", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleTagHelpers_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("value", "Hello", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("text"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<p>Hola</p>\r\n<form>\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __tagHelperExecutionContext.Add(__InputTagHelper);
+ __InputTagHelper.FooProp = (string)__tagHelperAttribute_0.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</form>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.ir.txt
new file mode 100644
index 0000000000..818e754db8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleTagHelpers_Runtime.ir.txt
@@ -0,0 +1,26 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleTagHelpers_Runtime - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [25] SimpleTagHelpers.cshtml)
+ IntermediateToken - (31:1,0 [3] SimpleTagHelpers.cshtml) - Html - <p>
+ IntermediateToken - (34:1,3 [4] SimpleTagHelpers.cshtml) - Html - Hola
+ IntermediateToken - (38:1,7 [4] SimpleTagHelpers.cshtml) - Html - </p>
+ IntermediateToken - (42:1,11 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (44:2,0 [6] SimpleTagHelpers.cshtml) - Html - <form>
+ IntermediateToken - (50:2,6 [6] SimpleTagHelpers.cshtml) - Html - \n
+ TagHelper - (56:3,4 [35] SimpleTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ PreallocatedTagHelperProperty - (70:3,18 [5] SimpleTagHelpers.cshtml) - __tagHelperAttribute_0 - value - FooProp
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (91:3,39 [9] SimpleTagHelpers.cshtml)
+ IntermediateToken - (91:3,39 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (93:4,0 [7] SimpleTagHelpers.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml
new file mode 100644
index 0000000000..27f2750eb2
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml
@@ -0,0 +1,4 @@
+@if (true)
+{
+ <div></div>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.codegen.cs
new file mode 100644
index 0000000000..0c8f87aa05
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.codegen.cs
@@ -0,0 +1,35 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleUnspacedIf_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml"
+ if (true)
+{
+
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml"
+
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.ir.txt
new file mode 100644
index 0000000000..fd92ecdec5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.ir.txt
@@ -0,0 +1,18 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleUnspacedIf_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [15] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (1:0,1 [15] SimpleUnspacedIf.cshtml) - CSharp - if (true)\n{\n
+ HtmlContent - (16:2,1 [11] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (16:2,1 [5] SimpleUnspacedIf.cshtml) - Html - <div>
+ IntermediateToken - (21:2,6 [6] SimpleUnspacedIf.cshtml) - Html - </div>
+ CSharpCode - (27:2,12 [3] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (27:2,12 [3] SimpleUnspacedIf.cshtml) - CSharp - \n}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.mappings.txt
new file mode 100644
index 0000000000..77c880477a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_DesignTime.mappings.txt
@@ -0,0 +1,16 @@
+Source Location: (1:0,1 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml)
+|if (true)
+{
+ |
+Generated Location: (732:18,1 [15] )
+|if (true)
+{
+ |
+
+Source Location: (27:2,12 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml)
+|
+}|
+Generated Location: (887:25,15 [3] )
+|
+}|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.codegen.cs
new file mode 100644
index 0000000000..d3af840b59
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.codegen.cs
@@ -0,0 +1,30 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "57877348e222dad68a66bed082fa64c96f925772"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleUnspacedIf_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"57877348e222dad68a66bed082fa64c96f925772", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleUnspacedIf_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml"
+ if (true)
+{
+
+#line default
+#line hidden
+ WriteLiteral("\t<div></div>\r\n");
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf.cshtml"
+}
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.ir.txt
new file mode 100644
index 0000000000..d12d18e89b
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SimpleUnspacedIf_Runtime.ir.txt
@@ -0,0 +1,15 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SimpleUnspacedIf_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (1:0,1 [14] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (1:0,1 [14] SimpleUnspacedIf.cshtml) - CSharp - if (true)\n{\n
+ HtmlContent - (15:2,0 [14] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (15:2,0 [1] SimpleUnspacedIf.cshtml) - Html -
+ IntermediateToken - (16:2,1 [5] SimpleUnspacedIf.cshtml) - Html - <div>
+ IntermediateToken - (21:2,6 [6] SimpleUnspacedIf.cshtml) - Html - </div>
+ IntermediateToken - (27:2,12 [2] SimpleUnspacedIf.cshtml) - Html - \n
+ CSharpCode - (29:3,0 [1] SimpleUnspacedIf.cshtml)
+ IntermediateToken - (29:3,0 [1] SimpleUnspacedIf.cshtml) - CSharp - }
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml
new file mode 100644
index 0000000000..6e12a5f3bf
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml
@@ -0,0 +1,3 @@
+@addTagHelper "*, TestAssembly"
+
+<p class="Hello World" age="1337">Body of Tag</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml
new file mode 100644
index 0000000000..b5c2eddf1a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml
@@ -0,0 +1,4 @@
+@addTagHelper "*, TestAssembly"
+
+<p
+ class="Hello World" age="1337">Body of Tag</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..fb63b233ff
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.codegen.cs
@@ -0,0 +1,33 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelperWithNewlineBeforeAttributes_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..caa51dd43d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.ir.txt
@@ -0,0 +1,27 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelperWithNewlineBeforeAttributes_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+ IntermediateToken - (31:0,31 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [53] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (73:3,34 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+ IntermediateToken - (73:3,34 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (49:3,10 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+ IntermediateToken - (49:3,10 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - Html - Hello World
+ DefaultTagHelperProperty - (67:3,28 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:3,28 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..47bfc7994d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+|"*, TestAssembly"|
+Generated Location: (526:11,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (67:3,28 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+|1337|
+Generated Location: (1106:24,33 [4] )
+|1337|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..e2e751c0ab
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.codegen.cs
@@ -0,0 +1,59 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "00f665efb7bd154c43f2bd30d287b9ed9fa2ffdd"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelperWithNewlineBeforeAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"00f665efb7bd154c43f2bd30d287b9ed9fa2ffdd", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelperWithNewlineBeforeAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Body of Tag");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..fb67e469d9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelperWithNewlineBeforeAttributes_Runtime.ir.txt
@@ -0,0 +1,20 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelperWithNewlineBeforeAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+ IntermediateToken - (33:1,0 [2] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - Html - \n
+ TagHelper - (35:2,0 [53] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (73:3,34 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml)
+ IntermediateToken - (73:3,34 [11] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (67:3,28 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (67:3,28 [4] SingleTagHelperWithNewlineBeforeAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.codegen.cs
new file mode 100644
index 0000000000..bba1ae1d82
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.codegen.cs
@@ -0,0 +1,33 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelper_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.ir.txt
new file mode 100644
index 0000000000..4749a67bfd
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.ir.txt
@@ -0,0 +1,27 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelper_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] SingleTagHelper.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] SingleTagHelper.cshtml)
+ IntermediateToken - (31:0,31 [4] SingleTagHelper.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [49] SingleTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (69:2,34 [11] SingleTagHelper.cshtml)
+ IntermediateToken - (69:2,34 [11] SingleTagHelper.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (45:2,10 [11] SingleTagHelper.cshtml)
+ IntermediateToken - (45:2,10 [11] SingleTagHelper.cshtml) - Html - Hello World
+ DefaultTagHelperProperty - (63:2,28 [4] SingleTagHelper.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (63:2,28 [4] SingleTagHelper.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.mappings.txt
new file mode 100644
index 0000000000..68565eaf3e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml)
+|"*, TestAssembly"|
+Generated Location: (499:11,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (63:2,28 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml)
+|1337|
+Generated Location: (1052:24,33 [4] )
+|1337|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.codegen.cs
new file mode 100644
index 0000000000..ff77e842d5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.codegen.cs
@@ -0,0 +1,59 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8cdee08b4e2681f8524ae09a405f163fd96d1ed8"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelper_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"8cdee08b4e2681f8524ae09a405f163fd96d1ed8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelper_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Body of Tag");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.ir.txt
new file mode 100644
index 0000000000..89ef050a2c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SingleTagHelper_Runtime.ir.txt
@@ -0,0 +1,20 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SingleTagHelper_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] SingleTagHelper.cshtml)
+ IntermediateToken - (33:1,0 [2] SingleTagHelper.cshtml) - Html - \n
+ TagHelper - (35:2,0 [49] SingleTagHelper.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (69:2,34 [11] SingleTagHelper.cshtml)
+ IntermediateToken - (69:2,34 [11] SingleTagHelper.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (63:2,28 [4] SingleTagHelper.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (63:2,28 [4] SingleTagHelper.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml
new file mode 100644
index 0000000000..19d498abfe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml
@@ -0,0 +1,237 @@
+<p>This is line 1</p>
+<p>This is line 2</p>
+<p>This is line 3</p>
+<p>This is line 4</p>
+<p>This is line 5</p>
+<p>This is line 6</p>
+<p>This is line 7</p>
+<p>This is line 8</p>
+<p>This is line 9</p>
+<p>This is line 10</p>
+<p>This is line 11</p>
+<p>This is line 12</p>
+<p>This is line 13</p>
+<p>This is line 14</p>
+<p>This is line 15</p>
+<p>This is line 16</p>
+<p>This is line 17</p>
+<p>This is line 18</p>
+<p>This is line 19</p>
+<p>This is line 20</p>
+<p>This is line 21</p>
+<p>This is line 22</p>
+<p>This is line 23</p>
+<p>This is line 24</p>
+<p>This is line 25</p>
+<p>This is line 26</p>
+<p>This is line 27</p>
+<p>This is line 28</p>
+<p>This is line 29</p>
+<p>This is line 30</p>
+<p>This is line 31</p>
+<p>This is line 32</p>
+<p>This is line 33</p>
+<p>This is line 34</p>
+<p>This is line 35</p>
+<p>This is line 36</p>
+<p>This is line 37</p>
+<p>This is line 38</p>
+<p>This is line 39</p>
+<p>This is line 40</p>
+<p>This is line 41</p>
+<p>This is line 42</p>
+<p>This is line 43</p>
+<p>This is line 44</p>
+<p>This is line 45</p>
+<p>This is line 46</p>
+<p>This is line 47</p>
+<p>This is line 48</p>
+<p>This is line 49</p>
+<p>This is line 50</p>
+<p>This is line 51</p>
+<p>This is line 52</p>
+<p>This is line 53</p>
+<p>This is line 54</p>
+<p>This is line 55</p>
+<p>This is line 56</p>
+<p>This is line 57</p>
+<p>This is line 58</p>
+<p>This is line 59</p>
+<p>This is line 60</p>
+<p>This is line 61</p>
+<p>This is line 62</p>
+<p>This is line 63</p>
+<p>This is line 64</p>
+<p>This is line 65</p>
+<p>This is line 66</p>
+<p>This is line 67</p>
+<p>This is line 68</p>
+<p>This is line 69</p>
+<p>This is line 70</p>
+<p>This is line 71</p>
+<p>This is line 72</p>
+<p>This is line 73</p>
+<p>This is line 74</p>
+<p>This is line 75</p>
+<p>This is line 76</p>
+<p>This is line 77</p>
+<p>This is line 78</p>
+<p>This is line 79</p>
+<p>This is line 80</p>
+<p>This is line 81</p>
+<p>This is line 82</p>
+<p>This is line 83</p>
+<p>This is line 84</p><br>
+
+@section WriteLiteralsToInHere {
+ <p>This is line 1 nested</p>
+ <p>This is line 2 nested</p>
+ <p>This is line 3 nested</p>
+ <p>This is line 4 nested</p>
+ <p>This is line 5 nested</p>
+ <p>This is line 6 nested</p>
+ <p>This is line 7 nested</p>
+ <p>This is line 8 nested</p>
+ <p>This is line 9 nested</p>
+ <p>This is line 10 nested</p>
+ <p>This is line 11 nested</p>
+ <p>This is line 12 nested</p>
+ <p>This is line 13 nested</p>
+ <p>This is line 14 nested</p>
+ <p>This is line 15 nested</p>
+ <p>This is line 16 nested</p>
+ <p>This is line 17 nested</p>
+ <p>This is line 18 nested</p>
+ <p>This is line 19 nested</p>
+ <p>This is line 20 nested</p>
+ <p>This is line 21 nested</p>
+ <p>This is line 22 nested</p>
+ <p>This is line 23 nested</p>
+ <p>This is line 24 nested</p>
+ <p>This is line 25 nested</p>
+ <p>This is line 26 nested</p>
+ <p>This is line 27 nested</p>
+ <p>This is line 28 nested</p>
+ <p>This is line 29 nested</p>
+ <p>This is line 30 nested</p>
+ <p>This is line 31 nested</p>
+ <p>This is line 32 nested</p>
+ <p>This is line 33 nested</p>
+ <p>This is line 34 nested</p>
+ <p>This is line 35 nested</p>
+ <p>This is line 36 nested</p>
+ <p>This is line 37 nested</p>
+ <p>This is line 38 nested</p>
+ <p>This is line 39 nested</p>
+ <p>This is line 40 nested</p>
+ <p>This is line 41 nested</p>
+ <p>This is line 42 nested</p>
+ <p>This is line 43 nested</p>
+ <p>This is line 44 nested</p>
+ <p>This is line 45 nested</p>
+ <p>This is line 46 nested</p>
+ <p>This is line 47 nested</p>
+ <p>This is line 48 nested</p>
+ <p>This is line 49 nested</p>
+ <p>This is line 50 nested</p>
+ <p>This is line 51 nested</p>
+ <p>This is line 52 nested</p>
+ <p>This is line 53 nested</p>
+ <p>This is line 54 nested</p>
+ <p>This is line 55 nested</p>
+ <p>This is line 56 nested</p>
+ <p>This is line 57 nested</p>
+ <p>This is line 58 nested</p>
+ <p>This is line 59 nested</p>
+ <p>This is line 60 nested</p>
+ <p>This is line 61 nested</p>
+ <p>This is line 62 nested</p>
+ <p>This is line 63 nested</p>
+ <p>This is line 64 nested</p>
+ <p>This is line 65 nested</p>
+ <p>This is line 66 nested</p>
+ <p>This is line 67 nested</p>
+ <p>This is line 68 nested</p>
+ <p>This is line 69 nested</p>
+ <p>This is line 70 nested</p>
+ <p>This is line 71 nested</p>
+ <p>This is line 72 nested</p>
+ <p>This is line 73 nested</p>
+ <p>This is line 74 nested</p>
+ <p>This is line 75 nested</p>
+}
+<p>This is line 1</p>
+<p>This is line 2</p>
+<p>This is line 3</p>
+<p>This is line 4</p>
+<p>This is line 5</p>
+<p>This is line 6</p>
+<p>This is line 7</p>
+<p>This is line 8</p>
+<p>This is line 9</p>
+<p>This is line 10</p>
+<p>This is line 11</p>
+<p>This is line 12</p>
+<p>This is line 13</p>
+<p>This is line 14</p>
+<p>This is line 15</p>
+<p>This is line 16</p>
+<p>This is line 17</p>
+<p>This is line 18</p>
+<p>This is line 19</p>
+<p>This is line 20</p>
+<p>This is line 21</p>
+<p>This is line 22</p>
+<p>This is line 23</p>
+<p>This is line 24</p>
+<p>This is line 25</p>
+<p>This is line 26</p>
+<p>This is line 27</p>
+<p>This is line 28</p>
+<p>This is line 29</p>
+<p>This is line 30</p>
+<p>This is line 31</p>
+<p>This is line 32</p>
+<p>This is line 33</p>
+<p>This is line 34</p>
+<p>This is line 35</p>
+<p>This is line 36</p>
+<p>This is line 37</p>
+<p>This is line 38</p>
+<p>This is line 39</p>
+<p>This is line 40</p>
+<p>This is line 41</p>
+<p>This is line 42</p>
+<p>This is line 43</p>hi!
+@section WriteLiteralsToInHereAlso {
+ <p>This is line 1 nested</p>
+ <p>This is line 2 nested</p>
+ <p>This is line 3 nested</p>
+ <p>This is line 4 nested</p>
+ <p>This is line 5 nested</p>
+ <p>This is line 6 nested</p>
+ <p>This is line 7 nested</p>
+ <p>This is line 8 nested</p>
+ <p>This is line 9 nested</p>
+ <p>This is line 10 nested</p>
+ <p>This is line 11 nested</p>
+ <p>This is line 12 nested</p>
+ <p>This is line 13 nested</p>
+ <p>This is line 14 nested</p>
+ <p>This is line 15 nested</p>
+ <p>This is line 16 nested</p>
+ <p>This is line 17 nested</p>
+ <p>This is line 18 nested</p>
+ <p>This is line 19 nested</p>
+ <p>This is line 20 nested</p>
+ <p>This is line 21 nested</p>
+ <p>This is line 22 nested</p>
+ <p>This is line 23 nested</p>
+ <p>This is line 24 nested</p>
+ <p>This is line 25 nested</p>
+ <p>This is line 26 nested</p>
+ <p>This is line 27 nested</p>
+ <p>This is line 28 nested</p>
+ <p>This is line 29 nested</p>
+ <p>30</p>
+}! \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.codegen.cs
new file mode 100644
index 0000000000..e1a96c0d30
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.codegen.cs
@@ -0,0 +1,36 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_StringLiterals_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object WriteLiteralsToInHere = null;
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object WriteLiteralsToInHereAlso = null;
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ DefineSection("WriteLiteralsToInHere", async(__razor_section_writer) => {
+ }
+ );
+ DefineSection("WriteLiteralsToInHereAlso", async(__razor_section_writer) => {
+ }
+ );
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.ir.txt
new file mode 100644
index 0000000000..f28592ba7e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.ir.txt
@@ -0,0 +1,953 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_StringLiterals_DesignTime - -
+ DesignTimeDirective -
+ DirectiveToken - (2022:85,9 [21] StringLiterals.cshtml) - WriteLiteralsToInHere
+ DirectiveToken - (5701:205,9 [25] StringLiterals.cshtml) - WriteLiteralsToInHereAlso
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [2013] StringLiterals.cshtml)
+ IntermediateToken - (0:0,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3:0,3 [14] StringLiterals.cshtml) - Html - This is line 1
+ IntermediateToken - (17:0,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (21:0,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (23:1,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (26:1,3 [14] StringLiterals.cshtml) - Html - This is line 2
+ IntermediateToken - (40:1,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (44:1,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (46:2,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (49:2,3 [14] StringLiterals.cshtml) - Html - This is line 3
+ IntermediateToken - (63:2,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (67:2,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (69:3,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (72:3,3 [14] StringLiterals.cshtml) - Html - This is line 4
+ IntermediateToken - (86:3,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (90:3,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (92:4,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (95:4,3 [14] StringLiterals.cshtml) - Html - This is line 5
+ IntermediateToken - (109:4,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (113:4,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (115:5,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (118:5,3 [14] StringLiterals.cshtml) - Html - This is line 6
+ IntermediateToken - (132:5,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (136:5,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (138:6,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (141:6,3 [14] StringLiterals.cshtml) - Html - This is line 7
+ IntermediateToken - (155:6,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (159:6,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (161:7,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (164:7,3 [14] StringLiterals.cshtml) - Html - This is line 8
+ IntermediateToken - (178:7,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (182:7,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (184:8,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (187:8,3 [14] StringLiterals.cshtml) - Html - This is line 9
+ IntermediateToken - (201:8,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (205:8,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (207:9,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (210:9,3 [15] StringLiterals.cshtml) - Html - This is line 10
+ IntermediateToken - (225:9,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (229:9,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (231:10,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (234:10,3 [15] StringLiterals.cshtml) - Html - This is line 11
+ IntermediateToken - (249:10,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (253:10,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (255:11,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (258:11,3 [15] StringLiterals.cshtml) - Html - This is line 12
+ IntermediateToken - (273:11,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (277:11,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (279:12,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (282:12,3 [15] StringLiterals.cshtml) - Html - This is line 13
+ IntermediateToken - (297:12,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (301:12,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (303:13,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (306:13,3 [15] StringLiterals.cshtml) - Html - This is line 14
+ IntermediateToken - (321:13,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (325:13,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (327:14,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (330:14,3 [15] StringLiterals.cshtml) - Html - This is line 15
+ IntermediateToken - (345:14,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (349:14,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (351:15,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (354:15,3 [15] StringLiterals.cshtml) - Html - This is line 16
+ IntermediateToken - (369:15,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (373:15,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (375:16,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (378:16,3 [15] StringLiterals.cshtml) - Html - This is line 17
+ IntermediateToken - (393:16,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (397:16,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (399:17,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (402:17,3 [15] StringLiterals.cshtml) - Html - This is line 18
+ IntermediateToken - (417:17,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (421:17,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (423:18,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (426:18,3 [15] StringLiterals.cshtml) - Html - This is line 19
+ IntermediateToken - (441:18,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (445:18,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (447:19,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (450:19,3 [15] StringLiterals.cshtml) - Html - This is line 20
+ IntermediateToken - (465:19,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (469:19,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (471:20,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (474:20,3 [15] StringLiterals.cshtml) - Html - This is line 21
+ IntermediateToken - (489:20,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (493:20,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (495:21,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (498:21,3 [15] StringLiterals.cshtml) - Html - This is line 22
+ IntermediateToken - (513:21,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (517:21,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (519:22,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (522:22,3 [15] StringLiterals.cshtml) - Html - This is line 23
+ IntermediateToken - (537:22,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (541:22,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (543:23,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (546:23,3 [15] StringLiterals.cshtml) - Html - This is line 24
+ IntermediateToken - (561:23,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (565:23,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (567:24,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (570:24,3 [15] StringLiterals.cshtml) - Html - This is line 25
+ IntermediateToken - (585:24,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (589:24,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (591:25,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (594:25,3 [15] StringLiterals.cshtml) - Html - This is line 26
+ IntermediateToken - (609:25,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (613:25,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (615:26,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (618:26,3 [15] StringLiterals.cshtml) - Html - This is line 27
+ IntermediateToken - (633:26,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (637:26,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (639:27,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (642:27,3 [15] StringLiterals.cshtml) - Html - This is line 28
+ IntermediateToken - (657:27,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (661:27,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (663:28,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (666:28,3 [15] StringLiterals.cshtml) - Html - This is line 29
+ IntermediateToken - (681:28,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (685:28,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (687:29,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (690:29,3 [15] StringLiterals.cshtml) - Html - This is line 30
+ IntermediateToken - (705:29,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (709:29,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (711:30,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (714:30,3 [15] StringLiterals.cshtml) - Html - This is line 31
+ IntermediateToken - (729:30,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (733:30,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (735:31,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (738:31,3 [15] StringLiterals.cshtml) - Html - This is line 32
+ IntermediateToken - (753:31,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (757:31,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (759:32,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (762:32,3 [15] StringLiterals.cshtml) - Html - This is line 33
+ IntermediateToken - (777:32,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (781:32,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (783:33,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (786:33,3 [15] StringLiterals.cshtml) - Html - This is line 34
+ IntermediateToken - (801:33,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (805:33,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (807:34,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (810:34,3 [15] StringLiterals.cshtml) - Html - This is line 35
+ IntermediateToken - (825:34,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (829:34,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (831:35,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (834:35,3 [15] StringLiterals.cshtml) - Html - This is line 36
+ IntermediateToken - (849:35,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (853:35,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (855:36,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (858:36,3 [15] StringLiterals.cshtml) - Html - This is line 37
+ IntermediateToken - (873:36,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (877:36,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (879:37,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (882:37,3 [15] StringLiterals.cshtml) - Html - This is line 38
+ IntermediateToken - (897:37,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (901:37,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (903:38,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (906:38,3 [15] StringLiterals.cshtml) - Html - This is line 39
+ IntermediateToken - (921:38,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (925:38,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (927:39,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (930:39,3 [15] StringLiterals.cshtml) - Html - This is line 40
+ IntermediateToken - (945:39,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (949:39,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (951:40,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (954:40,3 [15] StringLiterals.cshtml) - Html - This is line 41
+ IntermediateToken - (969:40,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (973:40,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (975:41,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (978:41,3 [15] StringLiterals.cshtml) - Html - This is line 42
+ IntermediateToken - (993:41,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (997:41,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (999:42,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1002:42,3 [15] StringLiterals.cshtml) - Html - This is line 43
+ IntermediateToken - (1017:42,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1021:42,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1023:43,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1026:43,3 [15] StringLiterals.cshtml) - Html - This is line 44
+ IntermediateToken - (1041:43,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1045:43,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1047:44,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1050:44,3 [15] StringLiterals.cshtml) - Html - This is line 45
+ IntermediateToken - (1065:44,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1069:44,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1071:45,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1074:45,3 [15] StringLiterals.cshtml) - Html - This is line 46
+ IntermediateToken - (1089:45,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1093:45,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1095:46,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1098:46,3 [15] StringLiterals.cshtml) - Html - This is line 47
+ IntermediateToken - (1113:46,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1117:46,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1119:47,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1122:47,3 [15] StringLiterals.cshtml) - Html - This is line 48
+ IntermediateToken - (1137:47,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1141:47,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1143:48,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1146:48,3 [15] StringLiterals.cshtml) - Html - This is line 49
+ IntermediateToken - (1161:48,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1165:48,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1167:49,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1170:49,3 [15] StringLiterals.cshtml) - Html - This is line 50
+ IntermediateToken - (1185:49,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1189:49,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1191:50,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1194:50,3 [15] StringLiterals.cshtml) - Html - This is line 51
+ IntermediateToken - (1209:50,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1213:50,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1215:51,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1218:51,3 [15] StringLiterals.cshtml) - Html - This is line 52
+ IntermediateToken - (1233:51,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1237:51,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1239:52,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1242:52,3 [15] StringLiterals.cshtml) - Html - This is line 53
+ IntermediateToken - (1257:52,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1261:52,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1263:53,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1266:53,3 [15] StringLiterals.cshtml) - Html - This is line 54
+ IntermediateToken - (1281:53,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1285:53,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1287:54,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1290:54,3 [15] StringLiterals.cshtml) - Html - This is line 55
+ IntermediateToken - (1305:54,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1309:54,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1311:55,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1314:55,3 [15] StringLiterals.cshtml) - Html - This is line 56
+ IntermediateToken - (1329:55,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1333:55,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1335:56,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1338:56,3 [15] StringLiterals.cshtml) - Html - This is line 57
+ IntermediateToken - (1353:56,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1357:56,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1359:57,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1362:57,3 [15] StringLiterals.cshtml) - Html - This is line 58
+ IntermediateToken - (1377:57,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1381:57,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1383:58,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1386:58,3 [15] StringLiterals.cshtml) - Html - This is line 59
+ IntermediateToken - (1401:58,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1405:58,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1407:59,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1410:59,3 [15] StringLiterals.cshtml) - Html - This is line 60
+ IntermediateToken - (1425:59,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1429:59,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1431:60,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1434:60,3 [15] StringLiterals.cshtml) - Html - This is line 61
+ IntermediateToken - (1449:60,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1453:60,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1455:61,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1458:61,3 [15] StringLiterals.cshtml) - Html - This is line 62
+ IntermediateToken - (1473:61,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1477:61,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1479:62,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1482:62,3 [15] StringLiterals.cshtml) - Html - This is line 63
+ IntermediateToken - (1497:62,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1501:62,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1503:63,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1506:63,3 [15] StringLiterals.cshtml) - Html - This is line 64
+ IntermediateToken - (1521:63,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1525:63,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1527:64,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1530:64,3 [15] StringLiterals.cshtml) - Html - This is line 65
+ IntermediateToken - (1545:64,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1549:64,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1551:65,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1554:65,3 [15] StringLiterals.cshtml) - Html - This is line 66
+ IntermediateToken - (1569:65,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1573:65,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1575:66,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1578:66,3 [15] StringLiterals.cshtml) - Html - This is line 67
+ IntermediateToken - (1593:66,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1597:66,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1599:67,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1602:67,3 [15] StringLiterals.cshtml) - Html - This is line 68
+ IntermediateToken - (1617:67,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1621:67,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1623:68,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1626:68,3 [15] StringLiterals.cshtml) - Html - This is line 69
+ IntermediateToken - (1641:68,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1645:68,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1647:69,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1650:69,3 [15] StringLiterals.cshtml) - Html - This is line 70
+ IntermediateToken - (1665:69,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1669:69,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1671:70,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1674:70,3 [15] StringLiterals.cshtml) - Html - This is line 71
+ IntermediateToken - (1689:70,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1693:70,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1695:71,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1698:71,3 [15] StringLiterals.cshtml) - Html - This is line 72
+ IntermediateToken - (1713:71,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1717:71,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1719:72,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1722:72,3 [15] StringLiterals.cshtml) - Html - This is line 73
+ IntermediateToken - (1737:72,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1741:72,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1743:73,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1746:73,3 [15] StringLiterals.cshtml) - Html - This is line 74
+ IntermediateToken - (1761:73,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1765:73,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1767:74,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1770:74,3 [15] StringLiterals.cshtml) - Html - This is line 75
+ IntermediateToken - (1785:74,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1789:74,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1791:75,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1794:75,3 [15] StringLiterals.cshtml) - Html - This is line 76
+ IntermediateToken - (1809:75,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1813:75,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1815:76,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1818:76,3 [15] StringLiterals.cshtml) - Html - This is line 77
+ IntermediateToken - (1833:76,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1837:76,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1839:77,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1842:77,3 [15] StringLiterals.cshtml) - Html - This is line 78
+ IntermediateToken - (1857:77,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1861:77,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1863:78,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1866:78,3 [15] StringLiterals.cshtml) - Html - This is line 79
+ IntermediateToken - (1881:78,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1885:78,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1887:79,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1890:79,3 [15] StringLiterals.cshtml) - Html - This is line 80
+ IntermediateToken - (1905:79,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1909:79,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1911:80,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1914:80,3 [15] StringLiterals.cshtml) - Html - This is line 81
+ IntermediateToken - (1929:80,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1933:80,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1935:81,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1938:81,3 [15] StringLiterals.cshtml) - Html - This is line 82
+ IntermediateToken - (1953:81,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1957:81,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1959:82,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1962:82,3 [15] StringLiterals.cshtml) - Html - This is line 83
+ IntermediateToken - (1977:82,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1981:82,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1983:83,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1986:83,3 [15] StringLiterals.cshtml) - Html - This is line 84
+ IntermediateToken - (2001:83,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2005:83,22 [4] StringLiterals.cshtml) - Html - <br>
+ IntermediateToken - (2009:83,26 [4] StringLiterals.cshtml) - Html - \n\n
+ Section - - WriteLiteralsToInHere
+ HtmlContent - (2045:85,32 [2618] StringLiterals.cshtml)
+ IntermediateToken - (2045:85,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2051:86,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2054:86,7 [21] StringLiterals.cshtml) - Html - This is line 1 nested
+ IntermediateToken - (2075:86,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2079:86,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2085:87,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2088:87,7 [21] StringLiterals.cshtml) - Html - This is line 2 nested
+ IntermediateToken - (2109:87,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2113:87,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2119:88,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2122:88,7 [21] StringLiterals.cshtml) - Html - This is line 3 nested
+ IntermediateToken - (2143:88,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2147:88,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2153:89,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2156:89,7 [21] StringLiterals.cshtml) - Html - This is line 4 nested
+ IntermediateToken - (2177:89,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2181:89,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2187:90,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2190:90,7 [21] StringLiterals.cshtml) - Html - This is line 5 nested
+ IntermediateToken - (2211:90,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2215:90,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2221:91,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2224:91,7 [21] StringLiterals.cshtml) - Html - This is line 6 nested
+ IntermediateToken - (2245:91,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2249:91,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2255:92,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2258:92,7 [21] StringLiterals.cshtml) - Html - This is line 7 nested
+ IntermediateToken - (2279:92,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2283:92,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2289:93,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2292:93,7 [21] StringLiterals.cshtml) - Html - This is line 8 nested
+ IntermediateToken - (2313:93,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2317:93,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2323:94,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2326:94,7 [21] StringLiterals.cshtml) - Html - This is line 9 nested
+ IntermediateToken - (2347:94,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2351:94,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2357:95,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2360:95,7 [22] StringLiterals.cshtml) - Html - This is line 10 nested
+ IntermediateToken - (2382:95,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2386:95,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2392:96,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2395:96,7 [22] StringLiterals.cshtml) - Html - This is line 11 nested
+ IntermediateToken - (2417:96,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2421:96,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2427:97,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2430:97,7 [22] StringLiterals.cshtml) - Html - This is line 12 nested
+ IntermediateToken - (2452:97,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2456:97,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2462:98,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2465:98,7 [22] StringLiterals.cshtml) - Html - This is line 13 nested
+ IntermediateToken - (2487:98,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2491:98,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2497:99,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2500:99,7 [22] StringLiterals.cshtml) - Html - This is line 14 nested
+ IntermediateToken - (2522:99,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2526:99,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2532:100,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2535:100,7 [22] StringLiterals.cshtml) - Html - This is line 15 nested
+ IntermediateToken - (2557:100,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2561:100,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2567:101,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2570:101,7 [22] StringLiterals.cshtml) - Html - This is line 16 nested
+ IntermediateToken - (2592:101,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2596:101,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2602:102,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2605:102,7 [22] StringLiterals.cshtml) - Html - This is line 17 nested
+ IntermediateToken - (2627:102,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2631:102,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2637:103,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2640:103,7 [22] StringLiterals.cshtml) - Html - This is line 18 nested
+ IntermediateToken - (2662:103,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2666:103,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2672:104,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2675:104,7 [22] StringLiterals.cshtml) - Html - This is line 19 nested
+ IntermediateToken - (2697:104,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2701:104,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2707:105,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2710:105,7 [22] StringLiterals.cshtml) - Html - This is line 20 nested
+ IntermediateToken - (2732:105,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2736:105,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2742:106,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2745:106,7 [22] StringLiterals.cshtml) - Html - This is line 21 nested
+ IntermediateToken - (2767:106,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2771:106,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2777:107,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2780:107,7 [22] StringLiterals.cshtml) - Html - This is line 22 nested
+ IntermediateToken - (2802:107,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2806:107,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2812:108,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2815:108,7 [22] StringLiterals.cshtml) - Html - This is line 23 nested
+ IntermediateToken - (2837:108,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2841:108,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2847:109,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2850:109,7 [22] StringLiterals.cshtml) - Html - This is line 24 nested
+ IntermediateToken - (2872:109,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2876:109,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2882:110,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2885:110,7 [22] StringLiterals.cshtml) - Html - This is line 25 nested
+ IntermediateToken - (2907:110,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2911:110,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2917:111,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2920:111,7 [22] StringLiterals.cshtml) - Html - This is line 26 nested
+ IntermediateToken - (2942:111,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2946:111,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2952:112,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2955:112,7 [22] StringLiterals.cshtml) - Html - This is line 27 nested
+ IntermediateToken - (2977:112,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2981:112,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2987:113,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2990:113,7 [22] StringLiterals.cshtml) - Html - This is line 28 nested
+ IntermediateToken - (3012:113,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3016:113,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3022:114,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3025:114,7 [22] StringLiterals.cshtml) - Html - This is line 29 nested
+ IntermediateToken - (3047:114,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3051:114,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3057:115,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3060:115,7 [22] StringLiterals.cshtml) - Html - This is line 30 nested
+ IntermediateToken - (3082:115,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3086:115,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3092:116,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3095:116,7 [22] StringLiterals.cshtml) - Html - This is line 31 nested
+ IntermediateToken - (3117:116,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3121:116,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3127:117,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3130:117,7 [22] StringLiterals.cshtml) - Html - This is line 32 nested
+ IntermediateToken - (3152:117,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3156:117,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3162:118,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3165:118,7 [22] StringLiterals.cshtml) - Html - This is line 33 nested
+ IntermediateToken - (3187:118,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3191:118,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3197:119,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3200:119,7 [22] StringLiterals.cshtml) - Html - This is line 34 nested
+ IntermediateToken - (3222:119,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3226:119,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3232:120,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3235:120,7 [22] StringLiterals.cshtml) - Html - This is line 35 nested
+ IntermediateToken - (3257:120,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3261:120,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3267:121,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3270:121,7 [22] StringLiterals.cshtml) - Html - This is line 36 nested
+ IntermediateToken - (3292:121,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3296:121,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3302:122,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3305:122,7 [22] StringLiterals.cshtml) - Html - This is line 37 nested
+ IntermediateToken - (3327:122,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3331:122,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3337:123,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3340:123,7 [22] StringLiterals.cshtml) - Html - This is line 38 nested
+ IntermediateToken - (3362:123,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3366:123,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3372:124,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3375:124,7 [22] StringLiterals.cshtml) - Html - This is line 39 nested
+ IntermediateToken - (3397:124,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3401:124,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3407:125,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3410:125,7 [22] StringLiterals.cshtml) - Html - This is line 40 nested
+ IntermediateToken - (3432:125,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3436:125,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3442:126,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3445:126,7 [22] StringLiterals.cshtml) - Html - This is line 41 nested
+ IntermediateToken - (3467:126,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3471:126,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3477:127,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3480:127,7 [22] StringLiterals.cshtml) - Html - This is line 42 nested
+ IntermediateToken - (3502:127,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3506:127,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3512:128,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3515:128,7 [22] StringLiterals.cshtml) - Html - This is line 43 nested
+ IntermediateToken - (3537:128,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3541:128,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3547:129,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3550:129,7 [22] StringLiterals.cshtml) - Html - This is line 44 nested
+ IntermediateToken - (3572:129,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3576:129,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3582:130,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3585:130,7 [22] StringLiterals.cshtml) - Html - This is line 45 nested
+ IntermediateToken - (3607:130,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3611:130,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3617:131,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3620:131,7 [22] StringLiterals.cshtml) - Html - This is line 46 nested
+ IntermediateToken - (3642:131,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3646:131,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3652:132,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3655:132,7 [22] StringLiterals.cshtml) - Html - This is line 47 nested
+ IntermediateToken - (3677:132,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3681:132,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3687:133,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3690:133,7 [22] StringLiterals.cshtml) - Html - This is line 48 nested
+ IntermediateToken - (3712:133,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3716:133,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3722:134,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3725:134,7 [22] StringLiterals.cshtml) - Html - This is line 49 nested
+ IntermediateToken - (3747:134,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3751:134,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3757:135,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3760:135,7 [22] StringLiterals.cshtml) - Html - This is line 50 nested
+ IntermediateToken - (3782:135,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3786:135,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3792:136,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3795:136,7 [22] StringLiterals.cshtml) - Html - This is line 51 nested
+ IntermediateToken - (3817:136,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3821:136,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3827:137,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3830:137,7 [22] StringLiterals.cshtml) - Html - This is line 52 nested
+ IntermediateToken - (3852:137,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3856:137,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3862:138,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3865:138,7 [22] StringLiterals.cshtml) - Html - This is line 53 nested
+ IntermediateToken - (3887:138,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3891:138,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3897:139,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3900:139,7 [22] StringLiterals.cshtml) - Html - This is line 54 nested
+ IntermediateToken - (3922:139,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3926:139,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3932:140,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3935:140,7 [22] StringLiterals.cshtml) - Html - This is line 55 nested
+ IntermediateToken - (3957:140,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3961:140,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3967:141,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3970:141,7 [22] StringLiterals.cshtml) - Html - This is line 56 nested
+ IntermediateToken - (3992:141,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3996:141,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4002:142,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4005:142,7 [22] StringLiterals.cshtml) - Html - This is line 57 nested
+ IntermediateToken - (4027:142,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4031:142,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4037:143,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4040:143,7 [22] StringLiterals.cshtml) - Html - This is line 58 nested
+ IntermediateToken - (4062:143,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4066:143,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4072:144,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4075:144,7 [22] StringLiterals.cshtml) - Html - This is line 59 nested
+ IntermediateToken - (4097:144,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4101:144,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4107:145,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4110:145,7 [22] StringLiterals.cshtml) - Html - This is line 60 nested
+ IntermediateToken - (4132:145,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4136:145,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4142:146,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4145:146,7 [22] StringLiterals.cshtml) - Html - This is line 61 nested
+ IntermediateToken - (4167:146,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4171:146,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4177:147,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4180:147,7 [22] StringLiterals.cshtml) - Html - This is line 62 nested
+ IntermediateToken - (4202:147,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4206:147,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4212:148,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4215:148,7 [22] StringLiterals.cshtml) - Html - This is line 63 nested
+ IntermediateToken - (4237:148,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4241:148,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4247:149,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4250:149,7 [22] StringLiterals.cshtml) - Html - This is line 64 nested
+ IntermediateToken - (4272:149,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4276:149,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4282:150,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4285:150,7 [22] StringLiterals.cshtml) - Html - This is line 65 nested
+ IntermediateToken - (4307:150,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4311:150,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4317:151,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4320:151,7 [22] StringLiterals.cshtml) - Html - This is line 66 nested
+ IntermediateToken - (4342:151,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4346:151,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4352:152,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4355:152,7 [22] StringLiterals.cshtml) - Html - This is line 67 nested
+ IntermediateToken - (4377:152,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4381:152,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4387:153,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4390:153,7 [22] StringLiterals.cshtml) - Html - This is line 68 nested
+ IntermediateToken - (4412:153,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4416:153,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4422:154,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4425:154,7 [22] StringLiterals.cshtml) - Html - This is line 69 nested
+ IntermediateToken - (4447:154,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4451:154,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4457:155,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4460:155,7 [22] StringLiterals.cshtml) - Html - This is line 70 nested
+ IntermediateToken - (4482:155,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4486:155,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4492:156,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4495:156,7 [22] StringLiterals.cshtml) - Html - This is line 71 nested
+ IntermediateToken - (4517:156,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4521:156,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4527:157,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4530:157,7 [22] StringLiterals.cshtml) - Html - This is line 72 nested
+ IntermediateToken - (4552:157,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4556:157,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4562:158,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4565:158,7 [22] StringLiterals.cshtml) - Html - This is line 73 nested
+ IntermediateToken - (4587:158,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4591:158,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4597:159,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4600:159,7 [22] StringLiterals.cshtml) - Html - This is line 74 nested
+ IntermediateToken - (4622:159,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4626:159,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4632:160,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4635:160,7 [22] StringLiterals.cshtml) - Html - This is line 75 nested
+ IntermediateToken - (4657:160,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4661:160,33 [2] StringLiterals.cshtml) - Html - \n
+ HtmlContent - (4664:161,1 [1028] StringLiterals.cshtml)
+ IntermediateToken - (4664:161,1 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4666:162,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4669:162,3 [14] StringLiterals.cshtml) - Html - This is line 1
+ IntermediateToken - (4683:162,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4687:162,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4689:163,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4692:163,3 [14] StringLiterals.cshtml) - Html - This is line 2
+ IntermediateToken - (4706:163,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4710:163,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4712:164,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4715:164,3 [14] StringLiterals.cshtml) - Html - This is line 3
+ IntermediateToken - (4729:164,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4733:164,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4735:165,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4738:165,3 [14] StringLiterals.cshtml) - Html - This is line 4
+ IntermediateToken - (4752:165,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4756:165,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4758:166,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4761:166,3 [14] StringLiterals.cshtml) - Html - This is line 5
+ IntermediateToken - (4775:166,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4779:166,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4781:167,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4784:167,3 [14] StringLiterals.cshtml) - Html - This is line 6
+ IntermediateToken - (4798:167,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4802:167,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4804:168,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4807:168,3 [14] StringLiterals.cshtml) - Html - This is line 7
+ IntermediateToken - (4821:168,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4825:168,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4827:169,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4830:169,3 [14] StringLiterals.cshtml) - Html - This is line 8
+ IntermediateToken - (4844:169,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4848:169,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4850:170,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4853:170,3 [14] StringLiterals.cshtml) - Html - This is line 9
+ IntermediateToken - (4867:170,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4871:170,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4873:171,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4876:171,3 [15] StringLiterals.cshtml) - Html - This is line 10
+ IntermediateToken - (4891:171,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4895:171,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4897:172,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4900:172,3 [15] StringLiterals.cshtml) - Html - This is line 11
+ IntermediateToken - (4915:172,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4919:172,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4921:173,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4924:173,3 [15] StringLiterals.cshtml) - Html - This is line 12
+ IntermediateToken - (4939:173,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4943:173,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4945:174,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4948:174,3 [15] StringLiterals.cshtml) - Html - This is line 13
+ IntermediateToken - (4963:174,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4967:174,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4969:175,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4972:175,3 [15] StringLiterals.cshtml) - Html - This is line 14
+ IntermediateToken - (4987:175,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4991:175,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4993:176,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4996:176,3 [15] StringLiterals.cshtml) - Html - This is line 15
+ IntermediateToken - (5011:176,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5015:176,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5017:177,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5020:177,3 [15] StringLiterals.cshtml) - Html - This is line 16
+ IntermediateToken - (5035:177,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5039:177,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5041:178,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5044:178,3 [15] StringLiterals.cshtml) - Html - This is line 17
+ IntermediateToken - (5059:178,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5063:178,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5065:179,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5068:179,3 [15] StringLiterals.cshtml) - Html - This is line 18
+ IntermediateToken - (5083:179,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5087:179,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5089:180,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5092:180,3 [15] StringLiterals.cshtml) - Html - This is line 19
+ IntermediateToken - (5107:180,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5111:180,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5113:181,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5116:181,3 [15] StringLiterals.cshtml) - Html - This is line 20
+ IntermediateToken - (5131:181,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5135:181,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5137:182,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5140:182,3 [15] StringLiterals.cshtml) - Html - This is line 21
+ IntermediateToken - (5155:182,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5159:182,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5161:183,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5164:183,3 [15] StringLiterals.cshtml) - Html - This is line 22
+ IntermediateToken - (5179:183,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5183:183,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5185:184,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5188:184,3 [15] StringLiterals.cshtml) - Html - This is line 23
+ IntermediateToken - (5203:184,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5207:184,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5209:185,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5212:185,3 [15] StringLiterals.cshtml) - Html - This is line 24
+ IntermediateToken - (5227:185,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5231:185,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5233:186,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5236:186,3 [15] StringLiterals.cshtml) - Html - This is line 25
+ IntermediateToken - (5251:186,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5255:186,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5257:187,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5260:187,3 [15] StringLiterals.cshtml) - Html - This is line 26
+ IntermediateToken - (5275:187,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5279:187,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5281:188,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5284:188,3 [15] StringLiterals.cshtml) - Html - This is line 27
+ IntermediateToken - (5299:188,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5303:188,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5305:189,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5308:189,3 [15] StringLiterals.cshtml) - Html - This is line 28
+ IntermediateToken - (5323:189,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5327:189,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5329:190,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5332:190,3 [15] StringLiterals.cshtml) - Html - This is line 29
+ IntermediateToken - (5347:190,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5351:190,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5353:191,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5356:191,3 [15] StringLiterals.cshtml) - Html - This is line 30
+ IntermediateToken - (5371:191,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5375:191,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5377:192,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5380:192,3 [15] StringLiterals.cshtml) - Html - This is line 31
+ IntermediateToken - (5395:192,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5399:192,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5401:193,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5404:193,3 [15] StringLiterals.cshtml) - Html - This is line 32
+ IntermediateToken - (5419:193,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5423:193,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5425:194,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5428:194,3 [15] StringLiterals.cshtml) - Html - This is line 33
+ IntermediateToken - (5443:194,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5447:194,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5449:195,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5452:195,3 [15] StringLiterals.cshtml) - Html - This is line 34
+ IntermediateToken - (5467:195,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5471:195,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5473:196,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5476:196,3 [15] StringLiterals.cshtml) - Html - This is line 35
+ IntermediateToken - (5491:196,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5495:196,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5497:197,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5500:197,3 [15] StringLiterals.cshtml) - Html - This is line 36
+ IntermediateToken - (5515:197,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5519:197,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5521:198,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5524:198,3 [15] StringLiterals.cshtml) - Html - This is line 37
+ IntermediateToken - (5539:198,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5543:198,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5545:199,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5548:199,3 [15] StringLiterals.cshtml) - Html - This is line 38
+ IntermediateToken - (5563:199,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5567:199,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5569:200,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5572:200,3 [15] StringLiterals.cshtml) - Html - This is line 39
+ IntermediateToken - (5587:200,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5591:200,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5593:201,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5596:201,3 [15] StringLiterals.cshtml) - Html - This is line 40
+ IntermediateToken - (5611:201,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5615:201,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5617:202,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5620:202,3 [15] StringLiterals.cshtml) - Html - This is line 41
+ IntermediateToken - (5635:202,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5639:202,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5641:203,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5644:203,3 [15] StringLiterals.cshtml) - Html - This is line 42
+ IntermediateToken - (5659:203,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5663:203,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5665:204,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5668:204,3 [15] StringLiterals.cshtml) - Html - This is line 43
+ IntermediateToken - (5683:204,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5687:204,22 [5] StringLiterals.cshtml) - Html - hi!\n
+ Section - - WriteLiteralsToInHereAlso
+ HtmlContent - (5728:205,36 [1023] StringLiterals.cshtml)
+ IntermediateToken - (5728:205,36 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5734:206,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5737:206,7 [21] StringLiterals.cshtml) - Html - This is line 1 nested
+ IntermediateToken - (5758:206,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5762:206,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5768:207,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5771:207,7 [21] StringLiterals.cshtml) - Html - This is line 2 nested
+ IntermediateToken - (5792:207,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5796:207,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5802:208,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5805:208,7 [21] StringLiterals.cshtml) - Html - This is line 3 nested
+ IntermediateToken - (5826:208,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5830:208,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5836:209,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5839:209,7 [21] StringLiterals.cshtml) - Html - This is line 4 nested
+ IntermediateToken - (5860:209,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5864:209,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5870:210,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5873:210,7 [21] StringLiterals.cshtml) - Html - This is line 5 nested
+ IntermediateToken - (5894:210,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5898:210,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5904:211,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5907:211,7 [21] StringLiterals.cshtml) - Html - This is line 6 nested
+ IntermediateToken - (5928:211,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5932:211,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5938:212,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5941:212,7 [21] StringLiterals.cshtml) - Html - This is line 7 nested
+ IntermediateToken - (5962:212,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5966:212,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5972:213,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5975:213,7 [21] StringLiterals.cshtml) - Html - This is line 8 nested
+ IntermediateToken - (5996:213,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6000:213,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6006:214,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6009:214,7 [21] StringLiterals.cshtml) - Html - This is line 9 nested
+ IntermediateToken - (6030:214,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6034:214,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6040:215,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6043:215,7 [22] StringLiterals.cshtml) - Html - This is line 10 nested
+ IntermediateToken - (6065:215,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6069:215,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6075:216,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6078:216,7 [22] StringLiterals.cshtml) - Html - This is line 11 nested
+ IntermediateToken - (6100:216,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6104:216,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6110:217,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6113:217,7 [22] StringLiterals.cshtml) - Html - This is line 12 nested
+ IntermediateToken - (6135:217,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6139:217,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6145:218,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6148:218,7 [22] StringLiterals.cshtml) - Html - This is line 13 nested
+ IntermediateToken - (6170:218,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6174:218,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6180:219,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6183:219,7 [22] StringLiterals.cshtml) - Html - This is line 14 nested
+ IntermediateToken - (6205:219,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6209:219,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6215:220,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6218:220,7 [22] StringLiterals.cshtml) - Html - This is line 15 nested
+ IntermediateToken - (6240:220,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6244:220,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6250:221,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6253:221,7 [22] StringLiterals.cshtml) - Html - This is line 16 nested
+ IntermediateToken - (6275:221,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6279:221,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6285:222,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6288:222,7 [22] StringLiterals.cshtml) - Html - This is line 17 nested
+ IntermediateToken - (6310:222,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6314:222,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6320:223,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6323:223,7 [22] StringLiterals.cshtml) - Html - This is line 18 nested
+ IntermediateToken - (6345:223,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6349:223,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6355:224,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6358:224,7 [22] StringLiterals.cshtml) - Html - This is line 19 nested
+ IntermediateToken - (6380:224,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6384:224,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6390:225,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6393:225,7 [22] StringLiterals.cshtml) - Html - This is line 20 nested
+ IntermediateToken - (6415:225,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6419:225,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6425:226,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6428:226,7 [22] StringLiterals.cshtml) - Html - This is line 21 nested
+ IntermediateToken - (6450:226,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6454:226,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6460:227,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6463:227,7 [22] StringLiterals.cshtml) - Html - This is line 22 nested
+ IntermediateToken - (6485:227,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6489:227,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6495:228,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6498:228,7 [22] StringLiterals.cshtml) - Html - This is line 23 nested
+ IntermediateToken - (6520:228,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6524:228,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6530:229,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6533:229,7 [22] StringLiterals.cshtml) - Html - This is line 24 nested
+ IntermediateToken - (6555:229,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6559:229,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6565:230,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6568:230,7 [22] StringLiterals.cshtml) - Html - This is line 25 nested
+ IntermediateToken - (6590:230,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6594:230,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6600:231,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6603:231,7 [22] StringLiterals.cshtml) - Html - This is line 26 nested
+ IntermediateToken - (6625:231,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6629:231,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6635:232,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6638:232,7 [22] StringLiterals.cshtml) - Html - This is line 27 nested
+ IntermediateToken - (6660:232,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6664:232,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6670:233,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6673:233,7 [22] StringLiterals.cshtml) - Html - This is line 28 nested
+ IntermediateToken - (6695:233,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6699:233,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6705:234,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6708:234,7 [22] StringLiterals.cshtml) - Html - This is line 29 nested
+ IntermediateToken - (6730:234,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6734:234,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6740:235,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6743:235,7 [2] StringLiterals.cshtml) - Html - 30
+ IntermediateToken - (6745:235,9 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6749:235,13 [2] StringLiterals.cshtml) - Html - \n
+ HtmlContent - (6752:236,1 [1] StringLiterals.cshtml)
+ IntermediateToken - (6752:236,1 [1] StringLiterals.cshtml) - Html - !
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.mappings.txt
new file mode 100644
index 0000000000..894e426da0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (2022:85,9 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml)
+|WriteLiteralsToInHere|
+Generated Location: (405:10,22 [21] )
+|WriteLiteralsToInHere|
+
+Source Location: (5701:205,9 [25] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml)
+|WriteLiteralsToInHereAlso|
+Generated Location: (518:14,22 [25] )
+|WriteLiteralsToInHereAlso|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.codegen.cs
new file mode 100644
index 0000000000..b2c587c14d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.codegen.cs
@@ -0,0 +1,267 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "711aea8060d90aea04acd3324afb4bb4a0caccde"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_StringLiterals_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"711aea8060d90aea04acd3324afb4bb4a0caccde", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_StringLiterals_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral(@"<p>This is line 1</p>
+<p>This is line 2</p>
+<p>This is line 3</p>
+<p>This is line 4</p>
+<p>This is line 5</p>
+<p>This is line 6</p>
+<p>This is line 7</p>
+<p>This is line 8</p>
+<p>This is line 9</p>
+<p>This is line 10</p>
+<p>This is line 11</p>
+<p>This is line 12</p>
+<p>This is line 13</p>
+<p>This is line 14</p>
+<p>This is line 15</p>
+<p>This is line 16</p>
+<p>This is line 17</p>
+<p>This is line 18</p>
+<p>This is line 19</p>
+<p>This is line 20</p>
+<p>This is line 21</p>
+<p>This is line 22</p>
+<p>This is line 23</p>
+<p>This is line 24</p>
+<p>This is line 25</p>
+<p>This is line 26</p>
+<p>This is line 27</p>
+<p>This is line 28</p>
+<p>This is line 29</p>
+<p>This is line 30</p>
+<p>This is line 31</p>
+<p>This is line 32</p>
+<p>This is line 33</p>
+<p>This is line 34</p>
+<p>This is line 35</p>
+<p>This is line 36</p>
+<p>This is line 37</p>
+<p>This is line 38</p>
+<p>This is line 39</p>
+<p>This is line 40</p>
+<p>This is line 41</p>
+<p>This is line 42</p>
+<p>This is line 43</p>
+<");
+ WriteLiteral(@"p>This is line 44</p>
+<p>This is line 45</p>
+<p>This is line 46</p>
+<p>This is line 47</p>
+<p>This is line 48</p>
+<p>This is line 49</p>
+<p>This is line 50</p>
+<p>This is line 51</p>
+<p>This is line 52</p>
+<p>This is line 53</p>
+<p>This is line 54</p>
+<p>This is line 55</p>
+<p>This is line 56</p>
+<p>This is line 57</p>
+<p>This is line 58</p>
+<p>This is line 59</p>
+<p>This is line 60</p>
+<p>This is line 61</p>
+<p>This is line 62</p>
+<p>This is line 63</p>
+<p>This is line 64</p>
+<p>This is line 65</p>
+<p>This is line 66</p>
+<p>This is line 67</p>
+<p>This is line 68</p>
+<p>This is line 69</p>
+<p>This is line 70</p>
+<p>This is line 71</p>
+<p>This is line 72</p>
+<p>This is line 73</p>
+<p>This is line 74</p>
+<p>This is line 75</p>
+<p>This is line 76</p>
+<p>This is line 77</p>
+<p>This is line 78</p>
+<p>This is line 79</p>
+<p>This is line 80</p>
+<p>This is line 81</p>
+<p>This is line 82</p>
+<p>This is line 83</p>
+<p>This is line 84</p><br>
+
+");
+ DefineSection("WriteLiteralsToInHere", async() => {
+ WriteLiteral(@"
+ <p>This is line 1 nested</p>
+ <p>This is line 2 nested</p>
+ <p>This is line 3 nested</p>
+ <p>This is line 4 nested</p>
+ <p>This is line 5 nested</p>
+ <p>This is line 6 nested</p>
+ <p>This is line 7 nested</p>
+ <p>This is line 8 nested</p>
+ <p>This is line 9 nested</p>
+ <p>This is line 10 nested</p>
+ <p>This is line 11 nested</p>
+ <p>This is line 12 nested</p>
+ <p>This is line 13 nested</p>
+ <p>This is line 14 nested</p>
+ <p>This is line 15 nested</p>
+ <p>This is line 16 nested</p>
+ <p>This is line 17 nested</p>
+ <p>This is line 18 nested</p>
+ <p>This is line 19 nested</p>
+ <p>This is line 20 nested</p>
+ <p>This is line 21 nested</p>
+ <p>This is line 22 nested</p>
+ <p>This is line 23 nested</p>
+ <p>This is line 24 nested</p>
+ <p>This is line 25 nested</p>
+ <p>This is line 26 nested</p>
+ <p>This is line 27 nested</p>
+ <p>This is line 28 nested</p>
+ <p>This is line 29 nested</p>
+ <p>This is l");
+ WriteLiteral(@"ine 30 nested</p>
+ <p>This is line 31 nested</p>
+ <p>This is line 32 nested</p>
+ <p>This is line 33 nested</p>
+ <p>This is line 34 nested</p>
+ <p>This is line 35 nested</p>
+ <p>This is line 36 nested</p>
+ <p>This is line 37 nested</p>
+ <p>This is line 38 nested</p>
+ <p>This is line 39 nested</p>
+ <p>This is line 40 nested</p>
+ <p>This is line 41 nested</p>
+ <p>This is line 42 nested</p>
+ <p>This is line 43 nested</p>
+ <p>This is line 44 nested</p>
+ <p>This is line 45 nested</p>
+ <p>This is line 46 nested</p>
+ <p>This is line 47 nested</p>
+ <p>This is line 48 nested</p>
+ <p>This is line 49 nested</p>
+ <p>This is line 50 nested</p>
+ <p>This is line 51 nested</p>
+ <p>This is line 52 nested</p>
+ <p>This is line 53 nested</p>
+ <p>This is line 54 nested</p>
+ <p>This is line 55 nested</p>
+ <p>This is line 56 nested</p>
+ <p>This is line 57 nested</p>
+ <p>This is line 58 nested</p>
+ <p>This is line 59 ne");
+ WriteLiteral(@"sted</p>
+ <p>This is line 60 nested</p>
+ <p>This is line 61 nested</p>
+ <p>This is line 62 nested</p>
+ <p>This is line 63 nested</p>
+ <p>This is line 64 nested</p>
+ <p>This is line 65 nested</p>
+ <p>This is line 66 nested</p>
+ <p>This is line 67 nested</p>
+ <p>This is line 68 nested</p>
+ <p>This is line 69 nested</p>
+ <p>This is line 70 nested</p>
+ <p>This is line 71 nested</p>
+ <p>This is line 72 nested</p>
+ <p>This is line 73 nested</p>
+ <p>This is line 74 nested</p>
+ <p>This is line 75 nested</p>
+");
+ }
+ );
+ WriteLiteral(@"<p>This is line 1</p>
+<p>This is line 2</p>
+<p>This is line 3</p>
+<p>This is line 4</p>
+<p>This is line 5</p>
+<p>This is line 6</p>
+<p>This is line 7</p>
+<p>This is line 8</p>
+<p>This is line 9</p>
+<p>This is line 10</p>
+<p>This is line 11</p>
+<p>This is line 12</p>
+<p>This is line 13</p>
+<p>This is line 14</p>
+<p>This is line 15</p>
+<p>This is line 16</p>
+<p>This is line 17</p>
+<p>This is line 18</p>
+<p>This is line 19</p>
+<p>This is line 20</p>
+<p>This is line 21</p>
+<p>This is line 22</p>
+<p>This is line 23</p>
+<p>This is line 24</p>
+<p>This is line 25</p>
+<p>This is line 26</p>
+<p>This is line 27</p>
+<p>This is line 28</p>
+<p>This is line 29</p>
+<p>This is line 30</p>
+<p>This is line 31</p>
+<p>This is line 32</p>
+<p>This is line 33</p>
+<p>This is line 34</p>
+<p>This is line 35</p>
+<p>This is line 36</p>
+<p>This is line 37</p>
+<p>This is line 38</p>
+<p>This is line 39</p>
+<p>This is line 40</p>
+<p>This is line 41</p>
+<p>This is line 42</p>
+<p>This is line 43</p>hi!");
+ WriteLiteral("\r\n");
+ DefineSection("WriteLiteralsToInHereAlso", async() => {
+ WriteLiteral(@"
+ <p>This is line 1 nested</p>
+ <p>This is line 2 nested</p>
+ <p>This is line 3 nested</p>
+ <p>This is line 4 nested</p>
+ <p>This is line 5 nested</p>
+ <p>This is line 6 nested</p>
+ <p>This is line 7 nested</p>
+ <p>This is line 8 nested</p>
+ <p>This is line 9 nested</p>
+ <p>This is line 10 nested</p>
+ <p>This is line 11 nested</p>
+ <p>This is line 12 nested</p>
+ <p>This is line 13 nested</p>
+ <p>This is line 14 nested</p>
+ <p>This is line 15 nested</p>
+ <p>This is line 16 nested</p>
+ <p>This is line 17 nested</p>
+ <p>This is line 18 nested</p>
+ <p>This is line 19 nested</p>
+ <p>This is line 20 nested</p>
+ <p>This is line 21 nested</p>
+ <p>This is line 22 nested</p>
+ <p>This is line 23 nested</p>
+ <p>This is line 24 nested</p>
+ <p>This is line 25 nested</p>
+ <p>This is line 26 nested</p>
+ <p>This is line 27 nested</p>
+ <p>This is line 28 nested</p>
+ <p>This is line 29 nested</p>
+ <p>30</p>
+");
+ }
+ );
+ WriteLiteral("!");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.ir.txt
new file mode 100644
index 0000000000..33d3408bbe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/StringLiterals_Runtime.ir.txt
@@ -0,0 +1,945 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_StringLiterals_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [2013] StringLiterals.cshtml)
+ IntermediateToken - (0:0,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3:0,3 [14] StringLiterals.cshtml) - Html - This is line 1
+ IntermediateToken - (17:0,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (21:0,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (23:1,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (26:1,3 [14] StringLiterals.cshtml) - Html - This is line 2
+ IntermediateToken - (40:1,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (44:1,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (46:2,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (49:2,3 [14] StringLiterals.cshtml) - Html - This is line 3
+ IntermediateToken - (63:2,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (67:2,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (69:3,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (72:3,3 [14] StringLiterals.cshtml) - Html - This is line 4
+ IntermediateToken - (86:3,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (90:3,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (92:4,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (95:4,3 [14] StringLiterals.cshtml) - Html - This is line 5
+ IntermediateToken - (109:4,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (113:4,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (115:5,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (118:5,3 [14] StringLiterals.cshtml) - Html - This is line 6
+ IntermediateToken - (132:5,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (136:5,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (138:6,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (141:6,3 [14] StringLiterals.cshtml) - Html - This is line 7
+ IntermediateToken - (155:6,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (159:6,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (161:7,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (164:7,3 [14] StringLiterals.cshtml) - Html - This is line 8
+ IntermediateToken - (178:7,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (182:7,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (184:8,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (187:8,3 [14] StringLiterals.cshtml) - Html - This is line 9
+ IntermediateToken - (201:8,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (205:8,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (207:9,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (210:9,3 [15] StringLiterals.cshtml) - Html - This is line 10
+ IntermediateToken - (225:9,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (229:9,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (231:10,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (234:10,3 [15] StringLiterals.cshtml) - Html - This is line 11
+ IntermediateToken - (249:10,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (253:10,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (255:11,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (258:11,3 [15] StringLiterals.cshtml) - Html - This is line 12
+ IntermediateToken - (273:11,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (277:11,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (279:12,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (282:12,3 [15] StringLiterals.cshtml) - Html - This is line 13
+ IntermediateToken - (297:12,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (301:12,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (303:13,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (306:13,3 [15] StringLiterals.cshtml) - Html - This is line 14
+ IntermediateToken - (321:13,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (325:13,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (327:14,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (330:14,3 [15] StringLiterals.cshtml) - Html - This is line 15
+ IntermediateToken - (345:14,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (349:14,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (351:15,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (354:15,3 [15] StringLiterals.cshtml) - Html - This is line 16
+ IntermediateToken - (369:15,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (373:15,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (375:16,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (378:16,3 [15] StringLiterals.cshtml) - Html - This is line 17
+ IntermediateToken - (393:16,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (397:16,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (399:17,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (402:17,3 [15] StringLiterals.cshtml) - Html - This is line 18
+ IntermediateToken - (417:17,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (421:17,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (423:18,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (426:18,3 [15] StringLiterals.cshtml) - Html - This is line 19
+ IntermediateToken - (441:18,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (445:18,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (447:19,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (450:19,3 [15] StringLiterals.cshtml) - Html - This is line 20
+ IntermediateToken - (465:19,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (469:19,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (471:20,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (474:20,3 [15] StringLiterals.cshtml) - Html - This is line 21
+ IntermediateToken - (489:20,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (493:20,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (495:21,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (498:21,3 [15] StringLiterals.cshtml) - Html - This is line 22
+ IntermediateToken - (513:21,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (517:21,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (519:22,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (522:22,3 [15] StringLiterals.cshtml) - Html - This is line 23
+ IntermediateToken - (537:22,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (541:22,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (543:23,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (546:23,3 [15] StringLiterals.cshtml) - Html - This is line 24
+ IntermediateToken - (561:23,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (565:23,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (567:24,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (570:24,3 [15] StringLiterals.cshtml) - Html - This is line 25
+ IntermediateToken - (585:24,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (589:24,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (591:25,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (594:25,3 [15] StringLiterals.cshtml) - Html - This is line 26
+ IntermediateToken - (609:25,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (613:25,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (615:26,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (618:26,3 [15] StringLiterals.cshtml) - Html - This is line 27
+ IntermediateToken - (633:26,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (637:26,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (639:27,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (642:27,3 [15] StringLiterals.cshtml) - Html - This is line 28
+ IntermediateToken - (657:27,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (661:27,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (663:28,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (666:28,3 [15] StringLiterals.cshtml) - Html - This is line 29
+ IntermediateToken - (681:28,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (685:28,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (687:29,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (690:29,3 [15] StringLiterals.cshtml) - Html - This is line 30
+ IntermediateToken - (705:29,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (709:29,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (711:30,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (714:30,3 [15] StringLiterals.cshtml) - Html - This is line 31
+ IntermediateToken - (729:30,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (733:30,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (735:31,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (738:31,3 [15] StringLiterals.cshtml) - Html - This is line 32
+ IntermediateToken - (753:31,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (757:31,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (759:32,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (762:32,3 [15] StringLiterals.cshtml) - Html - This is line 33
+ IntermediateToken - (777:32,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (781:32,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (783:33,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (786:33,3 [15] StringLiterals.cshtml) - Html - This is line 34
+ IntermediateToken - (801:33,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (805:33,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (807:34,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (810:34,3 [15] StringLiterals.cshtml) - Html - This is line 35
+ IntermediateToken - (825:34,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (829:34,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (831:35,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (834:35,3 [15] StringLiterals.cshtml) - Html - This is line 36
+ IntermediateToken - (849:35,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (853:35,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (855:36,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (858:36,3 [15] StringLiterals.cshtml) - Html - This is line 37
+ IntermediateToken - (873:36,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (877:36,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (879:37,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (882:37,3 [15] StringLiterals.cshtml) - Html - This is line 38
+ IntermediateToken - (897:37,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (901:37,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (903:38,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (906:38,3 [15] StringLiterals.cshtml) - Html - This is line 39
+ IntermediateToken - (921:38,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (925:38,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (927:39,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (930:39,3 [15] StringLiterals.cshtml) - Html - This is line 40
+ IntermediateToken - (945:39,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (949:39,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (951:40,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (954:40,3 [15] StringLiterals.cshtml) - Html - This is line 41
+ IntermediateToken - (969:40,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (973:40,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (975:41,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (978:41,3 [15] StringLiterals.cshtml) - Html - This is line 42
+ IntermediateToken - (993:41,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (997:41,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (999:42,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1002:42,3 [15] StringLiterals.cshtml) - Html - This is line 43
+ IntermediateToken - (1017:42,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1021:42,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1023:43,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1026:43,3 [15] StringLiterals.cshtml) - Html - This is line 44
+ IntermediateToken - (1041:43,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1045:43,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1047:44,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1050:44,3 [15] StringLiterals.cshtml) - Html - This is line 45
+ IntermediateToken - (1065:44,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1069:44,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1071:45,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1074:45,3 [15] StringLiterals.cshtml) - Html - This is line 46
+ IntermediateToken - (1089:45,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1093:45,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1095:46,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1098:46,3 [15] StringLiterals.cshtml) - Html - This is line 47
+ IntermediateToken - (1113:46,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1117:46,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1119:47,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1122:47,3 [15] StringLiterals.cshtml) - Html - This is line 48
+ IntermediateToken - (1137:47,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1141:47,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1143:48,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1146:48,3 [15] StringLiterals.cshtml) - Html - This is line 49
+ IntermediateToken - (1161:48,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1165:48,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1167:49,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1170:49,3 [15] StringLiterals.cshtml) - Html - This is line 50
+ IntermediateToken - (1185:49,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1189:49,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1191:50,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1194:50,3 [15] StringLiterals.cshtml) - Html - This is line 51
+ IntermediateToken - (1209:50,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1213:50,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1215:51,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1218:51,3 [15] StringLiterals.cshtml) - Html - This is line 52
+ IntermediateToken - (1233:51,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1237:51,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1239:52,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1242:52,3 [15] StringLiterals.cshtml) - Html - This is line 53
+ IntermediateToken - (1257:52,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1261:52,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1263:53,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1266:53,3 [15] StringLiterals.cshtml) - Html - This is line 54
+ IntermediateToken - (1281:53,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1285:53,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1287:54,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1290:54,3 [15] StringLiterals.cshtml) - Html - This is line 55
+ IntermediateToken - (1305:54,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1309:54,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1311:55,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1314:55,3 [15] StringLiterals.cshtml) - Html - This is line 56
+ IntermediateToken - (1329:55,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1333:55,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1335:56,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1338:56,3 [15] StringLiterals.cshtml) - Html - This is line 57
+ IntermediateToken - (1353:56,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1357:56,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1359:57,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1362:57,3 [15] StringLiterals.cshtml) - Html - This is line 58
+ IntermediateToken - (1377:57,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1381:57,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1383:58,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1386:58,3 [15] StringLiterals.cshtml) - Html - This is line 59
+ IntermediateToken - (1401:58,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1405:58,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1407:59,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1410:59,3 [15] StringLiterals.cshtml) - Html - This is line 60
+ IntermediateToken - (1425:59,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1429:59,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1431:60,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1434:60,3 [15] StringLiterals.cshtml) - Html - This is line 61
+ IntermediateToken - (1449:60,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1453:60,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1455:61,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1458:61,3 [15] StringLiterals.cshtml) - Html - This is line 62
+ IntermediateToken - (1473:61,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1477:61,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1479:62,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1482:62,3 [15] StringLiterals.cshtml) - Html - This is line 63
+ IntermediateToken - (1497:62,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1501:62,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1503:63,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1506:63,3 [15] StringLiterals.cshtml) - Html - This is line 64
+ IntermediateToken - (1521:63,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1525:63,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1527:64,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1530:64,3 [15] StringLiterals.cshtml) - Html - This is line 65
+ IntermediateToken - (1545:64,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1549:64,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1551:65,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1554:65,3 [15] StringLiterals.cshtml) - Html - This is line 66
+ IntermediateToken - (1569:65,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1573:65,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1575:66,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1578:66,3 [15] StringLiterals.cshtml) - Html - This is line 67
+ IntermediateToken - (1593:66,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1597:66,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1599:67,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1602:67,3 [15] StringLiterals.cshtml) - Html - This is line 68
+ IntermediateToken - (1617:67,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1621:67,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1623:68,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1626:68,3 [15] StringLiterals.cshtml) - Html - This is line 69
+ IntermediateToken - (1641:68,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1645:68,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1647:69,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1650:69,3 [15] StringLiterals.cshtml) - Html - This is line 70
+ IntermediateToken - (1665:69,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1669:69,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1671:70,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1674:70,3 [15] StringLiterals.cshtml) - Html - This is line 71
+ IntermediateToken - (1689:70,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1693:70,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1695:71,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1698:71,3 [15] StringLiterals.cshtml) - Html - This is line 72
+ IntermediateToken - (1713:71,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1717:71,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1719:72,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1722:72,3 [15] StringLiterals.cshtml) - Html - This is line 73
+ IntermediateToken - (1737:72,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1741:72,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1743:73,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1746:73,3 [15] StringLiterals.cshtml) - Html - This is line 74
+ IntermediateToken - (1761:73,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1765:73,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1767:74,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1770:74,3 [15] StringLiterals.cshtml) - Html - This is line 75
+ IntermediateToken - (1785:74,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1789:74,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1791:75,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1794:75,3 [15] StringLiterals.cshtml) - Html - This is line 76
+ IntermediateToken - (1809:75,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1813:75,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1815:76,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1818:76,3 [15] StringLiterals.cshtml) - Html - This is line 77
+ IntermediateToken - (1833:76,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1837:76,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1839:77,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1842:77,3 [15] StringLiterals.cshtml) - Html - This is line 78
+ IntermediateToken - (1857:77,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1861:77,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1863:78,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1866:78,3 [15] StringLiterals.cshtml) - Html - This is line 79
+ IntermediateToken - (1881:78,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1885:78,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1887:79,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1890:79,3 [15] StringLiterals.cshtml) - Html - This is line 80
+ IntermediateToken - (1905:79,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1909:79,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1911:80,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1914:80,3 [15] StringLiterals.cshtml) - Html - This is line 81
+ IntermediateToken - (1929:80,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1933:80,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1935:81,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1938:81,3 [15] StringLiterals.cshtml) - Html - This is line 82
+ IntermediateToken - (1953:81,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1957:81,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1959:82,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1962:82,3 [15] StringLiterals.cshtml) - Html - This is line 83
+ IntermediateToken - (1977:82,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (1981:82,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (1983:83,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (1986:83,3 [15] StringLiterals.cshtml) - Html - This is line 84
+ IntermediateToken - (2001:83,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2005:83,22 [4] StringLiterals.cshtml) - Html - <br>
+ IntermediateToken - (2009:83,26 [4] StringLiterals.cshtml) - Html - \n\n
+ Section - - WriteLiteralsToInHere
+ HtmlContent - (2045:85,32 [2618] StringLiterals.cshtml)
+ IntermediateToken - (2045:85,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2051:86,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2054:86,7 [21] StringLiterals.cshtml) - Html - This is line 1 nested
+ IntermediateToken - (2075:86,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2079:86,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2085:87,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2088:87,7 [21] StringLiterals.cshtml) - Html - This is line 2 nested
+ IntermediateToken - (2109:87,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2113:87,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2119:88,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2122:88,7 [21] StringLiterals.cshtml) - Html - This is line 3 nested
+ IntermediateToken - (2143:88,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2147:88,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2153:89,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2156:89,7 [21] StringLiterals.cshtml) - Html - This is line 4 nested
+ IntermediateToken - (2177:89,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2181:89,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2187:90,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2190:90,7 [21] StringLiterals.cshtml) - Html - This is line 5 nested
+ IntermediateToken - (2211:90,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2215:90,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2221:91,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2224:91,7 [21] StringLiterals.cshtml) - Html - This is line 6 nested
+ IntermediateToken - (2245:91,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2249:91,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2255:92,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2258:92,7 [21] StringLiterals.cshtml) - Html - This is line 7 nested
+ IntermediateToken - (2279:92,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2283:92,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2289:93,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2292:93,7 [21] StringLiterals.cshtml) - Html - This is line 8 nested
+ IntermediateToken - (2313:93,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2317:93,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2323:94,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2326:94,7 [21] StringLiterals.cshtml) - Html - This is line 9 nested
+ IntermediateToken - (2347:94,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2351:94,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2357:95,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2360:95,7 [22] StringLiterals.cshtml) - Html - This is line 10 nested
+ IntermediateToken - (2382:95,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2386:95,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2392:96,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2395:96,7 [22] StringLiterals.cshtml) - Html - This is line 11 nested
+ IntermediateToken - (2417:96,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2421:96,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2427:97,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2430:97,7 [22] StringLiterals.cshtml) - Html - This is line 12 nested
+ IntermediateToken - (2452:97,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2456:97,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2462:98,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2465:98,7 [22] StringLiterals.cshtml) - Html - This is line 13 nested
+ IntermediateToken - (2487:98,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2491:98,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2497:99,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2500:99,7 [22] StringLiterals.cshtml) - Html - This is line 14 nested
+ IntermediateToken - (2522:99,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2526:99,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2532:100,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2535:100,7 [22] StringLiterals.cshtml) - Html - This is line 15 nested
+ IntermediateToken - (2557:100,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2561:100,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2567:101,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2570:101,7 [22] StringLiterals.cshtml) - Html - This is line 16 nested
+ IntermediateToken - (2592:101,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2596:101,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2602:102,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2605:102,7 [22] StringLiterals.cshtml) - Html - This is line 17 nested
+ IntermediateToken - (2627:102,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2631:102,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2637:103,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2640:103,7 [22] StringLiterals.cshtml) - Html - This is line 18 nested
+ IntermediateToken - (2662:103,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2666:103,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2672:104,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2675:104,7 [22] StringLiterals.cshtml) - Html - This is line 19 nested
+ IntermediateToken - (2697:104,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2701:104,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2707:105,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2710:105,7 [22] StringLiterals.cshtml) - Html - This is line 20 nested
+ IntermediateToken - (2732:105,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2736:105,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2742:106,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2745:106,7 [22] StringLiterals.cshtml) - Html - This is line 21 nested
+ IntermediateToken - (2767:106,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2771:106,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2777:107,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2780:107,7 [22] StringLiterals.cshtml) - Html - This is line 22 nested
+ IntermediateToken - (2802:107,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2806:107,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2812:108,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2815:108,7 [22] StringLiterals.cshtml) - Html - This is line 23 nested
+ IntermediateToken - (2837:108,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2841:108,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2847:109,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2850:109,7 [22] StringLiterals.cshtml) - Html - This is line 24 nested
+ IntermediateToken - (2872:109,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2876:109,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2882:110,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2885:110,7 [22] StringLiterals.cshtml) - Html - This is line 25 nested
+ IntermediateToken - (2907:110,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2911:110,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2917:111,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2920:111,7 [22] StringLiterals.cshtml) - Html - This is line 26 nested
+ IntermediateToken - (2942:111,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2946:111,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2952:112,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2955:112,7 [22] StringLiterals.cshtml) - Html - This is line 27 nested
+ IntermediateToken - (2977:112,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (2981:112,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (2987:113,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (2990:113,7 [22] StringLiterals.cshtml) - Html - This is line 28 nested
+ IntermediateToken - (3012:113,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3016:113,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3022:114,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3025:114,7 [22] StringLiterals.cshtml) - Html - This is line 29 nested
+ IntermediateToken - (3047:114,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3051:114,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3057:115,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3060:115,7 [22] StringLiterals.cshtml) - Html - This is line 30 nested
+ IntermediateToken - (3082:115,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3086:115,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3092:116,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3095:116,7 [22] StringLiterals.cshtml) - Html - This is line 31 nested
+ IntermediateToken - (3117:116,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3121:116,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3127:117,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3130:117,7 [22] StringLiterals.cshtml) - Html - This is line 32 nested
+ IntermediateToken - (3152:117,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3156:117,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3162:118,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3165:118,7 [22] StringLiterals.cshtml) - Html - This is line 33 nested
+ IntermediateToken - (3187:118,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3191:118,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3197:119,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3200:119,7 [22] StringLiterals.cshtml) - Html - This is line 34 nested
+ IntermediateToken - (3222:119,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3226:119,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3232:120,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3235:120,7 [22] StringLiterals.cshtml) - Html - This is line 35 nested
+ IntermediateToken - (3257:120,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3261:120,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3267:121,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3270:121,7 [22] StringLiterals.cshtml) - Html - This is line 36 nested
+ IntermediateToken - (3292:121,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3296:121,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3302:122,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3305:122,7 [22] StringLiterals.cshtml) - Html - This is line 37 nested
+ IntermediateToken - (3327:122,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3331:122,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3337:123,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3340:123,7 [22] StringLiterals.cshtml) - Html - This is line 38 nested
+ IntermediateToken - (3362:123,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3366:123,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3372:124,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3375:124,7 [22] StringLiterals.cshtml) - Html - This is line 39 nested
+ IntermediateToken - (3397:124,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3401:124,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3407:125,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3410:125,7 [22] StringLiterals.cshtml) - Html - This is line 40 nested
+ IntermediateToken - (3432:125,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3436:125,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3442:126,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3445:126,7 [22] StringLiterals.cshtml) - Html - This is line 41 nested
+ IntermediateToken - (3467:126,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3471:126,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3477:127,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3480:127,7 [22] StringLiterals.cshtml) - Html - This is line 42 nested
+ IntermediateToken - (3502:127,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3506:127,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3512:128,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3515:128,7 [22] StringLiterals.cshtml) - Html - This is line 43 nested
+ IntermediateToken - (3537:128,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3541:128,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3547:129,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3550:129,7 [22] StringLiterals.cshtml) - Html - This is line 44 nested
+ IntermediateToken - (3572:129,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3576:129,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3582:130,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3585:130,7 [22] StringLiterals.cshtml) - Html - This is line 45 nested
+ IntermediateToken - (3607:130,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3611:130,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3617:131,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3620:131,7 [22] StringLiterals.cshtml) - Html - This is line 46 nested
+ IntermediateToken - (3642:131,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3646:131,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3652:132,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3655:132,7 [22] StringLiterals.cshtml) - Html - This is line 47 nested
+ IntermediateToken - (3677:132,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3681:132,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3687:133,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3690:133,7 [22] StringLiterals.cshtml) - Html - This is line 48 nested
+ IntermediateToken - (3712:133,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3716:133,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3722:134,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3725:134,7 [22] StringLiterals.cshtml) - Html - This is line 49 nested
+ IntermediateToken - (3747:134,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3751:134,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3757:135,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3760:135,7 [22] StringLiterals.cshtml) - Html - This is line 50 nested
+ IntermediateToken - (3782:135,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3786:135,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3792:136,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3795:136,7 [22] StringLiterals.cshtml) - Html - This is line 51 nested
+ IntermediateToken - (3817:136,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3821:136,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3827:137,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3830:137,7 [22] StringLiterals.cshtml) - Html - This is line 52 nested
+ IntermediateToken - (3852:137,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3856:137,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3862:138,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3865:138,7 [22] StringLiterals.cshtml) - Html - This is line 53 nested
+ IntermediateToken - (3887:138,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3891:138,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3897:139,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3900:139,7 [22] StringLiterals.cshtml) - Html - This is line 54 nested
+ IntermediateToken - (3922:139,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3926:139,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3932:140,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3935:140,7 [22] StringLiterals.cshtml) - Html - This is line 55 nested
+ IntermediateToken - (3957:140,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3961:140,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (3967:141,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (3970:141,7 [22] StringLiterals.cshtml) - Html - This is line 56 nested
+ IntermediateToken - (3992:141,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (3996:141,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4002:142,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4005:142,7 [22] StringLiterals.cshtml) - Html - This is line 57 nested
+ IntermediateToken - (4027:142,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4031:142,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4037:143,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4040:143,7 [22] StringLiterals.cshtml) - Html - This is line 58 nested
+ IntermediateToken - (4062:143,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4066:143,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4072:144,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4075:144,7 [22] StringLiterals.cshtml) - Html - This is line 59 nested
+ IntermediateToken - (4097:144,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4101:144,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4107:145,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4110:145,7 [22] StringLiterals.cshtml) - Html - This is line 60 nested
+ IntermediateToken - (4132:145,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4136:145,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4142:146,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4145:146,7 [22] StringLiterals.cshtml) - Html - This is line 61 nested
+ IntermediateToken - (4167:146,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4171:146,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4177:147,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4180:147,7 [22] StringLiterals.cshtml) - Html - This is line 62 nested
+ IntermediateToken - (4202:147,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4206:147,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4212:148,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4215:148,7 [22] StringLiterals.cshtml) - Html - This is line 63 nested
+ IntermediateToken - (4237:148,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4241:148,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4247:149,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4250:149,7 [22] StringLiterals.cshtml) - Html - This is line 64 nested
+ IntermediateToken - (4272:149,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4276:149,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4282:150,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4285:150,7 [22] StringLiterals.cshtml) - Html - This is line 65 nested
+ IntermediateToken - (4307:150,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4311:150,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4317:151,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4320:151,7 [22] StringLiterals.cshtml) - Html - This is line 66 nested
+ IntermediateToken - (4342:151,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4346:151,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4352:152,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4355:152,7 [22] StringLiterals.cshtml) - Html - This is line 67 nested
+ IntermediateToken - (4377:152,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4381:152,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4387:153,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4390:153,7 [22] StringLiterals.cshtml) - Html - This is line 68 nested
+ IntermediateToken - (4412:153,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4416:153,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4422:154,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4425:154,7 [22] StringLiterals.cshtml) - Html - This is line 69 nested
+ IntermediateToken - (4447:154,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4451:154,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4457:155,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4460:155,7 [22] StringLiterals.cshtml) - Html - This is line 70 nested
+ IntermediateToken - (4482:155,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4486:155,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4492:156,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4495:156,7 [22] StringLiterals.cshtml) - Html - This is line 71 nested
+ IntermediateToken - (4517:156,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4521:156,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4527:157,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4530:157,7 [22] StringLiterals.cshtml) - Html - This is line 72 nested
+ IntermediateToken - (4552:157,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4556:157,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4562:158,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4565:158,7 [22] StringLiterals.cshtml) - Html - This is line 73 nested
+ IntermediateToken - (4587:158,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4591:158,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4597:159,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4600:159,7 [22] StringLiterals.cshtml) - Html - This is line 74 nested
+ IntermediateToken - (4622:159,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4626:159,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4632:160,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4635:160,7 [22] StringLiterals.cshtml) - Html - This is line 75 nested
+ IntermediateToken - (4657:160,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4661:160,33 [2] StringLiterals.cshtml) - Html - \n
+ HtmlContent - (4666:162,0 [1026] StringLiterals.cshtml)
+ IntermediateToken - (4666:162,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4669:162,3 [14] StringLiterals.cshtml) - Html - This is line 1
+ IntermediateToken - (4683:162,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4687:162,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4689:163,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4692:163,3 [14] StringLiterals.cshtml) - Html - This is line 2
+ IntermediateToken - (4706:163,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4710:163,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4712:164,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4715:164,3 [14] StringLiterals.cshtml) - Html - This is line 3
+ IntermediateToken - (4729:164,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4733:164,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4735:165,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4738:165,3 [14] StringLiterals.cshtml) - Html - This is line 4
+ IntermediateToken - (4752:165,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4756:165,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4758:166,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4761:166,3 [14] StringLiterals.cshtml) - Html - This is line 5
+ IntermediateToken - (4775:166,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4779:166,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4781:167,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4784:167,3 [14] StringLiterals.cshtml) - Html - This is line 6
+ IntermediateToken - (4798:167,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4802:167,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4804:168,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4807:168,3 [14] StringLiterals.cshtml) - Html - This is line 7
+ IntermediateToken - (4821:168,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4825:168,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4827:169,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4830:169,3 [14] StringLiterals.cshtml) - Html - This is line 8
+ IntermediateToken - (4844:169,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4848:169,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4850:170,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4853:170,3 [14] StringLiterals.cshtml) - Html - This is line 9
+ IntermediateToken - (4867:170,17 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4871:170,21 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4873:171,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4876:171,3 [15] StringLiterals.cshtml) - Html - This is line 10
+ IntermediateToken - (4891:171,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4895:171,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4897:172,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4900:172,3 [15] StringLiterals.cshtml) - Html - This is line 11
+ IntermediateToken - (4915:172,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4919:172,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4921:173,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4924:173,3 [15] StringLiterals.cshtml) - Html - This is line 12
+ IntermediateToken - (4939:173,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4943:173,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4945:174,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4948:174,3 [15] StringLiterals.cshtml) - Html - This is line 13
+ IntermediateToken - (4963:174,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4967:174,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4969:175,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4972:175,3 [15] StringLiterals.cshtml) - Html - This is line 14
+ IntermediateToken - (4987:175,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (4991:175,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (4993:176,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (4996:176,3 [15] StringLiterals.cshtml) - Html - This is line 15
+ IntermediateToken - (5011:176,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5015:176,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5017:177,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5020:177,3 [15] StringLiterals.cshtml) - Html - This is line 16
+ IntermediateToken - (5035:177,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5039:177,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5041:178,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5044:178,3 [15] StringLiterals.cshtml) - Html - This is line 17
+ IntermediateToken - (5059:178,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5063:178,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5065:179,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5068:179,3 [15] StringLiterals.cshtml) - Html - This is line 18
+ IntermediateToken - (5083:179,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5087:179,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5089:180,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5092:180,3 [15] StringLiterals.cshtml) - Html - This is line 19
+ IntermediateToken - (5107:180,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5111:180,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5113:181,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5116:181,3 [15] StringLiterals.cshtml) - Html - This is line 20
+ IntermediateToken - (5131:181,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5135:181,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5137:182,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5140:182,3 [15] StringLiterals.cshtml) - Html - This is line 21
+ IntermediateToken - (5155:182,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5159:182,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5161:183,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5164:183,3 [15] StringLiterals.cshtml) - Html - This is line 22
+ IntermediateToken - (5179:183,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5183:183,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5185:184,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5188:184,3 [15] StringLiterals.cshtml) - Html - This is line 23
+ IntermediateToken - (5203:184,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5207:184,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5209:185,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5212:185,3 [15] StringLiterals.cshtml) - Html - This is line 24
+ IntermediateToken - (5227:185,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5231:185,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5233:186,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5236:186,3 [15] StringLiterals.cshtml) - Html - This is line 25
+ IntermediateToken - (5251:186,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5255:186,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5257:187,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5260:187,3 [15] StringLiterals.cshtml) - Html - This is line 26
+ IntermediateToken - (5275:187,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5279:187,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5281:188,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5284:188,3 [15] StringLiterals.cshtml) - Html - This is line 27
+ IntermediateToken - (5299:188,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5303:188,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5305:189,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5308:189,3 [15] StringLiterals.cshtml) - Html - This is line 28
+ IntermediateToken - (5323:189,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5327:189,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5329:190,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5332:190,3 [15] StringLiterals.cshtml) - Html - This is line 29
+ IntermediateToken - (5347:190,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5351:190,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5353:191,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5356:191,3 [15] StringLiterals.cshtml) - Html - This is line 30
+ IntermediateToken - (5371:191,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5375:191,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5377:192,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5380:192,3 [15] StringLiterals.cshtml) - Html - This is line 31
+ IntermediateToken - (5395:192,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5399:192,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5401:193,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5404:193,3 [15] StringLiterals.cshtml) - Html - This is line 32
+ IntermediateToken - (5419:193,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5423:193,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5425:194,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5428:194,3 [15] StringLiterals.cshtml) - Html - This is line 33
+ IntermediateToken - (5443:194,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5447:194,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5449:195,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5452:195,3 [15] StringLiterals.cshtml) - Html - This is line 34
+ IntermediateToken - (5467:195,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5471:195,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5473:196,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5476:196,3 [15] StringLiterals.cshtml) - Html - This is line 35
+ IntermediateToken - (5491:196,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5495:196,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5497:197,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5500:197,3 [15] StringLiterals.cshtml) - Html - This is line 36
+ IntermediateToken - (5515:197,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5519:197,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5521:198,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5524:198,3 [15] StringLiterals.cshtml) - Html - This is line 37
+ IntermediateToken - (5539:198,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5543:198,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5545:199,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5548:199,3 [15] StringLiterals.cshtml) - Html - This is line 38
+ IntermediateToken - (5563:199,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5567:199,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5569:200,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5572:200,3 [15] StringLiterals.cshtml) - Html - This is line 39
+ IntermediateToken - (5587:200,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5591:200,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5593:201,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5596:201,3 [15] StringLiterals.cshtml) - Html - This is line 40
+ IntermediateToken - (5611:201,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5615:201,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5617:202,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5620:202,3 [15] StringLiterals.cshtml) - Html - This is line 41
+ IntermediateToken - (5635:202,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5639:202,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5641:203,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5644:203,3 [15] StringLiterals.cshtml) - Html - This is line 42
+ IntermediateToken - (5659:203,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5663:203,22 [2] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5665:204,0 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5668:204,3 [15] StringLiterals.cshtml) - Html - This is line 43
+ IntermediateToken - (5683:204,18 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5687:204,22 [5] StringLiterals.cshtml) - Html - hi!\n
+ Section - - WriteLiteralsToInHereAlso
+ HtmlContent - (5728:205,36 [1023] StringLiterals.cshtml)
+ IntermediateToken - (5728:205,36 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5734:206,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5737:206,7 [21] StringLiterals.cshtml) - Html - This is line 1 nested
+ IntermediateToken - (5758:206,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5762:206,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5768:207,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5771:207,7 [21] StringLiterals.cshtml) - Html - This is line 2 nested
+ IntermediateToken - (5792:207,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5796:207,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5802:208,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5805:208,7 [21] StringLiterals.cshtml) - Html - This is line 3 nested
+ IntermediateToken - (5826:208,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5830:208,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5836:209,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5839:209,7 [21] StringLiterals.cshtml) - Html - This is line 4 nested
+ IntermediateToken - (5860:209,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5864:209,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5870:210,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5873:210,7 [21] StringLiterals.cshtml) - Html - This is line 5 nested
+ IntermediateToken - (5894:210,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5898:210,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5904:211,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5907:211,7 [21] StringLiterals.cshtml) - Html - This is line 6 nested
+ IntermediateToken - (5928:211,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5932:211,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5938:212,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5941:212,7 [21] StringLiterals.cshtml) - Html - This is line 7 nested
+ IntermediateToken - (5962:212,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (5966:212,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (5972:213,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (5975:213,7 [21] StringLiterals.cshtml) - Html - This is line 8 nested
+ IntermediateToken - (5996:213,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6000:213,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6006:214,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6009:214,7 [21] StringLiterals.cshtml) - Html - This is line 9 nested
+ IntermediateToken - (6030:214,28 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6034:214,32 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6040:215,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6043:215,7 [22] StringLiterals.cshtml) - Html - This is line 10 nested
+ IntermediateToken - (6065:215,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6069:215,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6075:216,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6078:216,7 [22] StringLiterals.cshtml) - Html - This is line 11 nested
+ IntermediateToken - (6100:216,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6104:216,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6110:217,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6113:217,7 [22] StringLiterals.cshtml) - Html - This is line 12 nested
+ IntermediateToken - (6135:217,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6139:217,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6145:218,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6148:218,7 [22] StringLiterals.cshtml) - Html - This is line 13 nested
+ IntermediateToken - (6170:218,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6174:218,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6180:219,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6183:219,7 [22] StringLiterals.cshtml) - Html - This is line 14 nested
+ IntermediateToken - (6205:219,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6209:219,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6215:220,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6218:220,7 [22] StringLiterals.cshtml) - Html - This is line 15 nested
+ IntermediateToken - (6240:220,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6244:220,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6250:221,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6253:221,7 [22] StringLiterals.cshtml) - Html - This is line 16 nested
+ IntermediateToken - (6275:221,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6279:221,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6285:222,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6288:222,7 [22] StringLiterals.cshtml) - Html - This is line 17 nested
+ IntermediateToken - (6310:222,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6314:222,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6320:223,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6323:223,7 [22] StringLiterals.cshtml) - Html - This is line 18 nested
+ IntermediateToken - (6345:223,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6349:223,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6355:224,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6358:224,7 [22] StringLiterals.cshtml) - Html - This is line 19 nested
+ IntermediateToken - (6380:224,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6384:224,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6390:225,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6393:225,7 [22] StringLiterals.cshtml) - Html - This is line 20 nested
+ IntermediateToken - (6415:225,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6419:225,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6425:226,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6428:226,7 [22] StringLiterals.cshtml) - Html - This is line 21 nested
+ IntermediateToken - (6450:226,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6454:226,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6460:227,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6463:227,7 [22] StringLiterals.cshtml) - Html - This is line 22 nested
+ IntermediateToken - (6485:227,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6489:227,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6495:228,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6498:228,7 [22] StringLiterals.cshtml) - Html - This is line 23 nested
+ IntermediateToken - (6520:228,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6524:228,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6530:229,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6533:229,7 [22] StringLiterals.cshtml) - Html - This is line 24 nested
+ IntermediateToken - (6555:229,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6559:229,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6565:230,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6568:230,7 [22] StringLiterals.cshtml) - Html - This is line 25 nested
+ IntermediateToken - (6590:230,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6594:230,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6600:231,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6603:231,7 [22] StringLiterals.cshtml) - Html - This is line 26 nested
+ IntermediateToken - (6625:231,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6629:231,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6635:232,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6638:232,7 [22] StringLiterals.cshtml) - Html - This is line 27 nested
+ IntermediateToken - (6660:232,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6664:232,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6670:233,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6673:233,7 [22] StringLiterals.cshtml) - Html - This is line 28 nested
+ IntermediateToken - (6695:233,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6699:233,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6705:234,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6708:234,7 [22] StringLiterals.cshtml) - Html - This is line 29 nested
+ IntermediateToken - (6730:234,29 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6734:234,33 [6] StringLiterals.cshtml) - Html - \n
+ IntermediateToken - (6740:235,4 [3] StringLiterals.cshtml) - Html - <p>
+ IntermediateToken - (6743:235,7 [2] StringLiterals.cshtml) - Html - 30
+ IntermediateToken - (6745:235,9 [4] StringLiterals.cshtml) - Html - </p>
+ IntermediateToken - (6749:235,13 [2] StringLiterals.cshtml) - Html - \n
+ HtmlContent - (6752:236,1 [1] StringLiterals.cshtml)
+ IntermediateToken - (6752:236,1 [1] StringLiterals.cshtml) - Html - !
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml
new file mode 100644
index 0000000000..c653cff1b3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml
@@ -0,0 +1,19 @@
+@addTagHelper *, TestAssembly
+
+<ul [item]="items"></ul>
+<ul [(item)]="items"></ul>
+<button (click)="doSomething()">Click Me</button>
+<button (^click)="doSomething()">Click Me</button>
+<template *something="value">
+</template>
+<div #local></div>
+<div #local="value"></div>
+
+<ul bound [item]="items" [item]="items"></ul>
+<ul bound [(item)]="items" [(item)]="items"></ul>
+<button bound (click)="doSomething()" (click)="doSomething()">Click Me</button>
+<button bound (^click)="doSomething()" (^click)="doSomething()">Click Me</button>
+<template bound *something="value" *something="value">
+</template>
+<div bound #localminimized></div>
+<div bound #local="value" #local="value"></div> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..2c45a0431f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.codegen.cs
@@ -0,0 +1,56 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SymbolBoundAttributes_DesignTime
+ {
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.ListItems = items;
+
+#line default
+#line hidden
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.ArrayItems = items;
+
+#line default
+#line hidden
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.Event1 = doSomething();
+
+#line default
+#line hidden
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+#line 15 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.Event2 = doSomething();
+
+#line default
+#line hidden
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_CatchAllTagHelper.StringProperty1 = "value";
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __TestNamespace_CatchAllTagHelper.StringProperty2 = "value";
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..1ee160ff70
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.diagnostics.txt
@@ -0,0 +1,5 @@
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[item]' because the name contains a '[' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[item]' because the name contains a ']' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.String[] TestNamespace.CatchAllTagHelper.ArrayItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[(item)]' because the name contains a '[' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.String[] TestNamespace.CatchAllTagHelper.ArrayItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[(item)]' because the name contains a ']' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'string TestNamespace.CatchAllTagHelper.StringProperty1' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '*something' because the name contains a '*' character.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..5315700a1a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.ir.txt
@@ -0,0 +1,140 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SymbolBoundAttributes_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] SymbolBoundAttributes.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [255] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (29:0,29 [4] SymbolBoundAttributes.cshtml) - Html - \n\n
+ IntermediateToken - (33:2,0 [3] SymbolBoundAttributes.cshtml) - Html - <ul
+ IntermediateToken - (36:2,3 [15] SymbolBoundAttributes.cshtml) - Html - [item]="items"
+ IntermediateToken - (51:2,18 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (52:2,19 [5] SymbolBoundAttributes.cshtml) - Html - </ul>
+ IntermediateToken - (57:2,24 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (59:3,0 [3] SymbolBoundAttributes.cshtml) - Html - <ul
+ IntermediateToken - (62:3,3 [17] SymbolBoundAttributes.cshtml) - Html - [(item)]="items"
+ IntermediateToken - (79:3,20 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (80:3,21 [5] SymbolBoundAttributes.cshtml) - Html - </ul>
+ IntermediateToken - (85:3,26 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (87:4,0 [7] SymbolBoundAttributes.cshtml) - Html - <button
+ IntermediateToken - (94:4,7 [24] SymbolBoundAttributes.cshtml) - Html - (click)="doSomething()"
+ IntermediateToken - (118:4,31 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (119:4,32 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ IntermediateToken - (127:4,40 [9] SymbolBoundAttributes.cshtml) - Html - </button>
+ IntermediateToken - (136:4,49 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (138:5,0 [7] SymbolBoundAttributes.cshtml) - Html - <button
+ IntermediateToken - (145:5,7 [25] SymbolBoundAttributes.cshtml) - Html - (^click)="doSomething()"
+ IntermediateToken - (170:5,32 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (171:5,33 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ IntermediateToken - (179:5,41 [9] SymbolBoundAttributes.cshtml) - Html - </button>
+ IntermediateToken - (188:5,50 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (190:6,0 [9] SymbolBoundAttributes.cshtml) - Html - <template
+ IntermediateToken - (199:6,9 [19] SymbolBoundAttributes.cshtml) - Html - *something="value"
+ IntermediateToken - (218:6,28 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (219:6,29 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (221:7,0 [11] SymbolBoundAttributes.cshtml) - Html - </template>
+ IntermediateToken - (232:7,11 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (234:8,0 [4] SymbolBoundAttributes.cshtml) - Html - <div
+ IntermediateToken - (238:8,4 [7] SymbolBoundAttributes.cshtml) - Html - #local
+ IntermediateToken - (245:8,11 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (246:8,12 [6] SymbolBoundAttributes.cshtml) - Html - </div>
+ IntermediateToken - (252:8,18 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (254:9,0 [4] SymbolBoundAttributes.cshtml) - Html - <div
+ IntermediateToken - (258:9,4 [15] SymbolBoundAttributes.cshtml) - Html - #local="value"
+ IntermediateToken - (273:9,19 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (274:9,20 [6] SymbolBoundAttributes.cshtml) - Html - </div>
+ IntermediateToken - (280:9,26 [4] SymbolBoundAttributes.cshtml) - Html - \n\n
+ TagHelper - (284:11,0 [45] SymbolBoundAttributes.cshtml) - ul - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (302:11,18 [5] SymbolBoundAttributes.cshtml) - [item] - System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (302:11,18 [5] SymbolBoundAttributes.cshtml) - CSharp - items
+ DefaultTagHelperHtmlAttribute - - [item] - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (317:11,33 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (317:11,33 [5] SymbolBoundAttributes.cshtml) - Html - items
+ DefaultTagHelperExecute -
+ HtmlContent - (329:11,45 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (329:11,45 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (331:12,0 [49] SymbolBoundAttributes.cshtml) - ul - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (351:12,20 [5] SymbolBoundAttributes.cshtml) - [(item)] - System.String[] TestNamespace.CatchAllTagHelper.ArrayItems - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (351:12,20 [5] SymbolBoundAttributes.cshtml) - CSharp - items
+ DefaultTagHelperHtmlAttribute - - [(item)] - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (368:12,37 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (368:12,37 [5] SymbolBoundAttributes.cshtml) - Html - items
+ DefaultTagHelperExecute -
+ HtmlContent - (380:12,49 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (380:12,49 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (382:13,0 [79] SymbolBoundAttributes.cshtml) - button - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (444:13,62 [8] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (444:13,62 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (405:13,23 [13] SymbolBoundAttributes.cshtml) - (click) - System.Action TestNamespace.CatchAllTagHelper.Event1 - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (405:13,23 [13] SymbolBoundAttributes.cshtml) - CSharp - doSomething()
+ DefaultTagHelperHtmlAttribute - - (click) - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (429:13,47 [13] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (429:13,47 [13] SymbolBoundAttributes.cshtml) - Html - doSomething()
+ DefaultTagHelperExecute -
+ HtmlContent - (461:13,79 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (461:13,79 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (463:14,0 [81] SymbolBoundAttributes.cshtml) - button - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (527:14,64 [8] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (527:14,64 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (487:14,24 [13] SymbolBoundAttributes.cshtml) - (^click) - System.Action TestNamespace.CatchAllTagHelper.Event2 - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (487:14,24 [13] SymbolBoundAttributes.cshtml) - CSharp - doSomething()
+ DefaultTagHelperHtmlAttribute - - (^click) - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (512:14,49 [13] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (512:14,49 [13] SymbolBoundAttributes.cshtml) - Html - doSomething()
+ DefaultTagHelperExecute -
+ HtmlContent - (544:14,81 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (544:14,81 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (546:15,0 [67] SymbolBoundAttributes.cshtml) - template - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (600:15,54 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (600:15,54 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (574:15,28 [5] SymbolBoundAttributes.cshtml) - *something - string TestNamespace.CatchAllTagHelper.StringProperty1 - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (574:15,28 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (574:15,28 [5] SymbolBoundAttributes.cshtml) - Html - value
+ DefaultTagHelperHtmlAttribute - - *something - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (593:15,47 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (593:15,47 [5] SymbolBoundAttributes.cshtml) - Html - value
+ DefaultTagHelperExecute -
+ HtmlContent - (613:16,11 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (613:16,11 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (615:17,0 [33] SymbolBoundAttributes.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - #localminimized - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (648:17,33 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (648:17,33 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (650:18,0 [47] SymbolBoundAttributes.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (669:18,19 [5] SymbolBoundAttributes.cshtml) - #local - string TestNamespace.CatchAllTagHelper.StringProperty2 - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (669:18,19 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (669:18,19 [5] SymbolBoundAttributes.cshtml) - Html - value
+ DefaultTagHelperHtmlAttribute - - #local - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (684:18,34 [5] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (684:18,34 [5] SymbolBoundAttributes.cshtml) - Html - value
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..6538479806
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_DesignTime.mappings.txt
@@ -0,0 +1,25 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml)
+|*, TestAssembly|
+Generated Location: (520:11,38 [15] )
+|*, TestAssembly|
+
+Source Location: (302:11,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml)
+|items|
+Generated Location: (1106:24,46 [5] )
+|items|
+
+Source Location: (351:12,20 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml)
+|items|
+Generated Location: (1399:30,47 [5] )
+|items|
+
+Source Location: (405:13,23 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml)
+|doSomething()|
+Generated Location: (1688:36,43 [13] )
+|doSomething()|
+
+Source Location: (487:14,24 [13] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml)
+|doSomething()|
+Generated Location: (1985:42,43 [13] )
+|doSomething()|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..bac695f3ea
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.codegen.cs
@@ -0,0 +1,197 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "911fabc92d64c2732fa0cff025d454076241edb8"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SymbolBoundAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"911fabc92d64c2732fa0cff025d454076241edb8", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SymbolBoundAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("[item]", new global::Microsoft.AspNetCore.Html.HtmlString("items"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("[(item)]", new global::Microsoft.AspNetCore.Html.HtmlString("items"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("(click)", new global::Microsoft.AspNetCore.Html.HtmlString("doSomething()"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("(^click)", new global::Microsoft.AspNetCore.Html.HtmlString("doSomething()"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("*something", "value", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("*something", new global::Microsoft.AspNetCore.Html.HtmlString("value"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("#local", "value", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_7 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("#local", new global::Microsoft.AspNetCore.Html.HtmlString("value"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.CatchAllTagHelper __TestNamespace_CatchAllTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n<ul [item]=\"items\"></ul>\r\n<ul [(item)]=\"items\"></ul>\r\n<button (click)=\"doSomething()\">Click Me</button>\r\n<button (^click)=\"doSomething()\">Click Me</button>\r\n<template *something=\"value\">\r\n</template>\r\n<div #local></div>\r\n<div #local=\"value\"></div>\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("ul", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.ListItems = items;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("[item]", __TestNamespace_CatchAllTagHelper.ListItems, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("ul", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.ArrayItems = items;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("[(item)]", __TestNamespace_CatchAllTagHelper.ArrayItems, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("button", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Click Me");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+#line 14 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.Event1 = doSomething();
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("(click)", __TestNamespace_CatchAllTagHelper.Event1, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("button", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Click Me");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+#line 15 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes.cshtml"
+__TestNamespace_CatchAllTagHelper.Event2 = doSomething();
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("(^click)", __TestNamespace_CatchAllTagHelper.Event2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("template", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n");
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ __TestNamespace_CatchAllTagHelper.StringProperty1 = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("#localminimized", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_CatchAllTagHelper = CreateTagHelper<global::TestNamespace.CatchAllTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_CatchAllTagHelper);
+ BeginWriteTagHelperAttribute();
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("bound", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.Minimized);
+ __TestNamespace_CatchAllTagHelper.StringProperty2 = (string)__tagHelperAttribute_6.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_7);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..1ee160ff70
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.diagnostics.txt
@@ -0,0 +1,5 @@
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[item]' because the name contains a '[' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[item]' because the name contains a ']' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.String[] TestNamespace.CatchAllTagHelper.ArrayItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[(item)]' because the name contains a '[' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'System.String[] TestNamespace.CatchAllTagHelper.ArrayItems' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '[(item)]' because the name contains a ']' character.
+(0,0): Error RZ3003: Invalid tag helper bound property 'string TestNamespace.CatchAllTagHelper.StringProperty1' on tag helper 'TestNamespace.CatchAllTagHelper'. Tag helpers cannot bind to HTML attributes with name '*something' because the name contains a '*' character.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..ee4dc7af83
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/SymbolBoundAttributes_Runtime.ir.txt
@@ -0,0 +1,126 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_SymbolBoundAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - [item] - items - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - [(item)] - items - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - (click) - doSomething() - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - (^click) - doSomething() - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_4 - *something - value - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - *something - value - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_6 - #local - value - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_7 - #local - value - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.CatchAllTagHelper - __TestNamespace_CatchAllTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [253] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (31:1,0 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (33:2,0 [3] SymbolBoundAttributes.cshtml) - Html - <ul
+ IntermediateToken - (36:2,3 [15] SymbolBoundAttributes.cshtml) - Html - [item]="items"
+ IntermediateToken - (51:2,18 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (52:2,19 [5] SymbolBoundAttributes.cshtml) - Html - </ul>
+ IntermediateToken - (57:2,24 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (59:3,0 [3] SymbolBoundAttributes.cshtml) - Html - <ul
+ IntermediateToken - (62:3,3 [17] SymbolBoundAttributes.cshtml) - Html - [(item)]="items"
+ IntermediateToken - (79:3,20 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (80:3,21 [5] SymbolBoundAttributes.cshtml) - Html - </ul>
+ IntermediateToken - (85:3,26 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (87:4,0 [7] SymbolBoundAttributes.cshtml) - Html - <button
+ IntermediateToken - (94:4,7 [24] SymbolBoundAttributes.cshtml) - Html - (click)="doSomething()"
+ IntermediateToken - (118:4,31 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (119:4,32 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ IntermediateToken - (127:4,40 [9] SymbolBoundAttributes.cshtml) - Html - </button>
+ IntermediateToken - (136:4,49 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (138:5,0 [7] SymbolBoundAttributes.cshtml) - Html - <button
+ IntermediateToken - (145:5,7 [25] SymbolBoundAttributes.cshtml) - Html - (^click)="doSomething()"
+ IntermediateToken - (170:5,32 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (171:5,33 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ IntermediateToken - (179:5,41 [9] SymbolBoundAttributes.cshtml) - Html - </button>
+ IntermediateToken - (188:5,50 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (190:6,0 [9] SymbolBoundAttributes.cshtml) - Html - <template
+ IntermediateToken - (199:6,9 [19] SymbolBoundAttributes.cshtml) - Html - *something="value"
+ IntermediateToken - (218:6,28 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (219:6,29 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (221:7,0 [11] SymbolBoundAttributes.cshtml) - Html - </template>
+ IntermediateToken - (232:7,11 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (234:8,0 [4] SymbolBoundAttributes.cshtml) - Html - <div
+ IntermediateToken - (238:8,4 [7] SymbolBoundAttributes.cshtml) - Html - #local
+ IntermediateToken - (245:8,11 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (246:8,12 [6] SymbolBoundAttributes.cshtml) - Html - </div>
+ IntermediateToken - (252:8,18 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (254:9,0 [4] SymbolBoundAttributes.cshtml) - Html - <div
+ IntermediateToken - (258:9,4 [15] SymbolBoundAttributes.cshtml) - Html - #local="value"
+ IntermediateToken - (273:9,19 [1] SymbolBoundAttributes.cshtml) - Html - >
+ IntermediateToken - (274:9,20 [6] SymbolBoundAttributes.cshtml) - Html - </div>
+ IntermediateToken - (280:9,26 [4] SymbolBoundAttributes.cshtml) - Html - \n\n
+ TagHelper - (284:11,0 [45] SymbolBoundAttributes.cshtml) - ul - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (302:11,18 [5] SymbolBoundAttributes.cshtml) - [item] - System.Collections.Generic.List<string> TestNamespace.CatchAllTagHelper.ListItems - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (302:11,18 [5] SymbolBoundAttributes.cshtml) - CSharp - items
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (329:11,45 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (329:11,45 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (331:12,0 [49] SymbolBoundAttributes.cshtml) - ul - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (351:12,20 [5] SymbolBoundAttributes.cshtml) - [(item)] - System.String[] TestNamespace.CatchAllTagHelper.ArrayItems - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (351:12,20 [5] SymbolBoundAttributes.cshtml) - CSharp - items
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (380:12,49 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (380:12,49 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (382:13,0 [79] SymbolBoundAttributes.cshtml) - button - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (444:13,62 [8] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (444:13,62 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (405:13,23 [13] SymbolBoundAttributes.cshtml) - (click) - System.Action TestNamespace.CatchAllTagHelper.Event1 - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (405:13,23 [13] SymbolBoundAttributes.cshtml) - CSharp - doSomething()
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ HtmlContent - (461:13,79 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (461:13,79 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (463:14,0 [81] SymbolBoundAttributes.cshtml) - button - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (527:14,64 [8] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (527:14,64 [8] SymbolBoundAttributes.cshtml) - Html - Click Me
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperProperty - (487:14,24 [13] SymbolBoundAttributes.cshtml) - (^click) - System.Action TestNamespace.CatchAllTagHelper.Event2 - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (487:14,24 [13] SymbolBoundAttributes.cshtml) - CSharp - doSomething()
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ DefaultTagHelperExecute -
+ HtmlContent - (544:14,81 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (544:14,81 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (546:15,0 [67] SymbolBoundAttributes.cshtml) - template - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (600:15,54 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (600:15,54 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ PreallocatedTagHelperProperty - (574:15,28 [5] SymbolBoundAttributes.cshtml) - __tagHelperAttribute_4 - *something - StringProperty1
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ DefaultTagHelperExecute -
+ HtmlContent - (613:16,11 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (613:16,11 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (615:17,0 [33] SymbolBoundAttributes.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperHtmlAttribute - - #localminimized - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (648:17,33 [2] SymbolBoundAttributes.cshtml)
+ IntermediateToken - (648:17,33 [2] SymbolBoundAttributes.cshtml) - Html - \n
+ TagHelper - (650:18,0 [47] SymbolBoundAttributes.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.CatchAllTagHelper
+ DefaultTagHelperHtmlAttribute - - bound - HtmlAttributeValueStyle.Minimized
+ PreallocatedTagHelperProperty - (669:18,19 [5] SymbolBoundAttributes.cshtml) - __tagHelperAttribute_6 - #local - StringProperty2
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_7
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml
new file mode 100644
index 0000000000..08a8a9fde1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml
@@ -0,0 +1,14 @@
+@addTagHelper "*, TestAssembly"
+
+@{
+ var code = "some code";
+}
+
+@section MySection {
+ <div>
+ <mytaghelper boundproperty="Current Time: @DateTime.Now" unboundproperty="Current Time: @DateTime.Now">
+ In None ContentBehavior.
+ <nestedtaghelper>Some buffered values with @code</nestedtaghelper>
+ </mytaghelper>
+ </div>
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.codegen.cs
new file mode 100644
index 0000000000..7848d435fe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.codegen.cs
@@ -0,0 +1,102 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "deb5a34864edafd4c1c97e666199377d29fe23bd"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersInSection_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"deb5a34864edafd4c1c97e666199377d29fe23bd", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersInSection_Runtime
+ {
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.MyTagHelper __TestNamespace_MyTagHelper;
+ private global::TestNamespace.NestedTagHelper __TestNamespace_NestedTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml"
+
+ var code = "some code";
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+ DefineSection("MySection", async() => {
+ WriteLiteral("\r\n <div>\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("mytaghelper", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n In None ContentBehavior.\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("nestedtaghelper", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Some buffered values with ");
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml"
+ Write(code);
+
+#line default
+#line hidden
+ }
+ );
+ __TestNamespace_NestedTagHelper = CreateTagHelper<global::TestNamespace.NestedTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_NestedTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n ");
+ }
+ );
+ __TestNamespace_MyTagHelper = CreateTagHelper<global::TestNamespace.MyTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_MyTagHelper);
+ BeginWriteTagHelperAttribute();
+ WriteLiteral("Current Time: ");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml"
+ WriteLiteral(DateTime.Now);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __TestNamespace_MyTagHelper.BoundProperty = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("boundproperty", __TestNamespace_MyTagHelper.BoundProperty, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "unboundproperty", 3, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 188, "Current", 188, 7, true);
+ AddHtmlAttributeValue(" ", 195, "Time:", 196, 6, true);
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection.cshtml"
+AddHtmlAttributeValue(" ", 201, DateTime.Now, 202, 13, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n </div>\r\n");
+ }
+ );
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.ir.txt
new file mode 100644
index 0000000000..0b89183f3e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersInSection_Runtime.ir.txt
@@ -0,0 +1,54 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersInSection_Runtime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.MyTagHelper - __TestNamespace_MyTagHelper
+ FieldDeclaration - - private - global::TestNamespace.NestedTagHelper - __TestNamespace_NestedTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] TagHelpersInSection.cshtml)
+ IntermediateToken - (33:1,0 [2] TagHelpersInSection.cshtml) - Html - \n
+ CSharpCode - (37:2,2 [31] TagHelpersInSection.cshtml)
+ IntermediateToken - (37:2,2 [31] TagHelpersInSection.cshtml) - CSharp - \n var code = "some code";\n
+ HtmlContent - (71:5,0 [2] TagHelpersInSection.cshtml)
+ IntermediateToken - (71:5,0 [2] TagHelpersInSection.cshtml) - Html - \n
+ Section - - MySection
+ HtmlContent - (93:6,20 [21] TagHelpersInSection.cshtml)
+ IntermediateToken - (93:6,20 [6] TagHelpersInSection.cshtml) - Html - \n
+ IntermediateToken - (99:7,4 [5] TagHelpersInSection.cshtml) - Html - <div>
+ IntermediateToken - (104:7,9 [10] TagHelpersInSection.cshtml) - Html - \n
+ TagHelper - (114:8,8 [245] TagHelpersInSection.cshtml) - mytaghelper - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (217:8,111 [52] TagHelpersInSection.cshtml)
+ IntermediateToken - (217:8,111 [52] TagHelpersInSection.cshtml) - Html - \n In None ContentBehavior.\n
+ TagHelper - (269:10,12 [66] TagHelpersInSection.cshtml) - nestedtaghelper - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (286:10,29 [26] TagHelpersInSection.cshtml)
+ IntermediateToken - (286:10,29 [26] TagHelpersInSection.cshtml) - Html - Some buffered values with
+ CSharpExpression - (313:10,56 [4] TagHelpersInSection.cshtml)
+ IntermediateToken - (313:10,56 [4] TagHelpersInSection.cshtml) - CSharp - code
+ DefaultTagHelperCreate - - TestNamespace.NestedTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (335:10,78 [10] TagHelpersInSection.cshtml)
+ IntermediateToken - (335:10,78 [10] TagHelpersInSection.cshtml) - Html - \n
+ DefaultTagHelperCreate - - TestNamespace.MyTagHelper
+ DefaultTagHelperProperty - (142:8,36 [27] TagHelpersInSection.cshtml) - boundproperty - string TestNamespace.MyTagHelper.BoundProperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (142:8,36 [14] TagHelpersInSection.cshtml)
+ IntermediateToken - (142:8,36 [7] TagHelpersInSection.cshtml) - Html - Current
+ IntermediateToken - (149:8,43 [6] TagHelpersInSection.cshtml) - Html - Time:
+ IntermediateToken - (155:8,49 [1] TagHelpersInSection.cshtml) - Html -
+ CSharpExpression - (157:8,51 [12] TagHelpersInSection.cshtml)
+ IntermediateToken - (157:8,51 [12] TagHelpersInSection.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperHtmlAttribute - - unboundproperty - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (188:8,82 [7] TagHelpersInSection.cshtml) -
+ IntermediateToken - (188:8,82 [7] TagHelpersInSection.cshtml) - Html - Current
+ HtmlAttributeValue - (195:8,89 [6] TagHelpersInSection.cshtml) -
+ IntermediateToken - (196:8,90 [5] TagHelpersInSection.cshtml) - Html - Time:
+ CSharpExpressionAttributeValue - (201:8,95 [14] TagHelpersInSection.cshtml) -
+ IntermediateToken - (203:8,97 [12] TagHelpersInSection.cshtml) - CSharp - DateTime.Now
+ DefaultTagHelperExecute -
+ HtmlContent - (359:11,22 [14] TagHelpersInSection.cshtml)
+ IntermediateToken - (359:11,22 [6] TagHelpersInSection.cshtml) - Html - \n
+ IntermediateToken - (365:12,4 [6] TagHelpersInSection.cshtml) - Html - </div>
+ IntermediateToken - (371:12,10 [2] TagHelpersInSection.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml
new file mode 100644
index 0000000000..83023559d3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml
@@ -0,0 +1,4 @@
+@addTagHelper *, TestAssembly
+<form>
+ <input bound=@Hello type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..f875e4d082
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.codegen.cs
@@ -0,0 +1,34 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithBoundAttributes_DesignTime
+ {
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml"
+ __o = Hello;
+
+#line default
+#line hidden
+ __InputTagHelper.BoundProp = string.Empty;
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..07f6b5e459
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.ir.txt
@@ -0,0 +1,31 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithBoundAttributes_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] TagHelpersWithBoundAttributes.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [14] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (29:0,29 [2] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (31:1,0 [6] TagHelpersWithBoundAttributes.cshtml) - Html - <form>
+ IntermediateToken - (37:1,6 [6] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ TagHelper - (43:2,4 [34] TagHelpersWithBoundAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (56:2,17 [6] TagHelpersWithBoundAttributes.cshtml) - bound - string InputTagHelper.BoundProp - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - CSharp - Hello
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (69:2,30 [4] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (69:2,30 [4] TagHelpersWithBoundAttributes.cshtml) - Html - text
+ DefaultTagHelperExecute -
+ HtmlContent - (77:2,38 [9] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (77:2,38 [2] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (79:3,0 [7] TagHelpersWithBoundAttributes.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..597eef56ac
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_DesignTime.mappings.txt
@@ -0,0 +1,10 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml)
+|*, TestAssembly|
+Generated Location: (494:11,38 [15] )
+|*, TestAssembly|
+
+Source Location: (57:2,18 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml)
+|Hello|
+Generated Location: (1025:24,18 [5] )
+|Hello|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..acaa25cdb0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.codegen.cs
@@ -0,0 +1,62 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "111aa585040c2e45a0dac3f5bdb65ee0252748d2"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithBoundAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"111aa585040c2e45a0dac3f5bdb65ee0252748d2", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithBoundAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("text"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<form>\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __tagHelperExecutionContext.Add(__InputTagHelper);
+ BeginWriteTagHelperAttribute();
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes.cshtml"
+ WriteLiteral(Hello);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __InputTagHelper.BoundProp = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("bound", __InputTagHelper.BoundProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</form>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..c3d5ddf52e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithBoundAttributes_Runtime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithBoundAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [12] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (31:1,0 [6] TagHelpersWithBoundAttributes.cshtml) - Html - <form>
+ IntermediateToken - (37:1,6 [6] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ TagHelper - (43:2,4 [34] TagHelpersWithBoundAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (56:2,17 [6] TagHelpersWithBoundAttributes.cshtml) - bound - string InputTagHelper.BoundProp - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - CSharp - Hello
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (77:2,38 [9] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (77:2,38 [2] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (79:3,0 [7] TagHelpersWithBoundAttributes.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml
new file mode 100644
index 0000000000..e365dd4d60
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml
@@ -0,0 +1,5 @@
+@addTagHelper *, TestAssembly
+@tagHelperPrefix cool:
+<form>
+ <cool:input bound=@Hello type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.codegen.cs
new file mode 100644
index 0000000000..9d9b99ec91
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.codegen.cs
@@ -0,0 +1,38 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithPrefix_DesignTime
+ {
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "cool:";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml"
+ __o = Hello;
+
+#line default
+#line hidden
+ __InputTagHelper.BoundProp = string.Empty;
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.ir.txt
new file mode 100644
index 0000000000..34ef66d880
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.ir.txt
@@ -0,0 +1,34 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithPrefix_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [15] TagHelpersWithPrefix.cshtml) - *, TestAssembly
+ DirectiveToken - (48:1,17 [5] TagHelpersWithPrefix.cshtml) - cool:
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (29:0,29 [2] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (29:0,29 [2] TagHelpersWithPrefix.cshtml) - Html - \n
+ HtmlContent - (53:1,22 [14] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (53:1,22 [2] TagHelpersWithPrefix.cshtml) - Html - \n
+ IntermediateToken - (55:2,0 [6] TagHelpersWithPrefix.cshtml) - Html - <form>
+ IntermediateToken - (61:2,6 [6] TagHelpersWithPrefix.cshtml) - Html - \n
+ TagHelper - (67:3,4 [39] TagHelpersWithPrefix.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (85:3,22 [6] TagHelpersWithPrefix.cshtml) - bound - string InputTagHelper.BoundProp - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (86:3,23 [5] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (86:3,23 [5] TagHelpersWithPrefix.cshtml) - CSharp - Hello
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (98:3,35 [4] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (98:3,35 [4] TagHelpersWithPrefix.cshtml) - Html - text
+ DefaultTagHelperExecute -
+ HtmlContent - (106:3,43 [9] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (106:3,43 [2] TagHelpersWithPrefix.cshtml) - Html - \n
+ IntermediateToken - (108:4,0 [7] TagHelpersWithPrefix.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.mappings.txt
new file mode 100644
index 0000000000..f44871f2b6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_DesignTime.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (14:0,14 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml)
+|*, TestAssembly|
+Generated Location: (485:11,38 [15] )
+|*, TestAssembly|
+
+Source Location: (48:1,17 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml)
+|cool:|
+Generated Location: (602:15,38 [5] )
+|cool:|
+
+Source Location: (86:3,23 [5] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml)
+|Hello|
+Generated Location: (1119:28,23 [5] )
+|Hello|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.codegen.cs
new file mode 100644
index 0000000000..a12f078f29
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.codegen.cs
@@ -0,0 +1,62 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5c97c003c8158f389b506a6dbc47e468892ec57d"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithPrefix_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"5c97c003c8158f389b506a6dbc47e468892ec57d", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithPrefix_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("text"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<form>\r\n ");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __tagHelperExecutionContext.Add(__InputTagHelper);
+ BeginWriteTagHelperAttribute();
+#line 4 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix.cshtml"
+ WriteLiteral(Hello);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __InputTagHelper.BoundProp = __tagHelperStringValueBuffer;
+ __tagHelperExecutionContext.AddTagHelperAttribute("bound", __InputTagHelper.BoundProp, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n</form>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.ir.txt
new file mode 100644
index 0000000000..6d6437abfc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithPrefix_Runtime.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithPrefix_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (55:2,0 [12] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (55:2,0 [6] TagHelpersWithPrefix.cshtml) - Html - <form>
+ IntermediateToken - (61:2,6 [6] TagHelpersWithPrefix.cshtml) - Html - \n
+ TagHelper - (67:3,4 [39] TagHelpersWithPrefix.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (85:3,22 [6] TagHelpersWithPrefix.cshtml) - bound - string InputTagHelper.BoundProp - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (86:3,23 [5] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (86:3,23 [5] TagHelpersWithPrefix.cshtml) - CSharp - Hello
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (106:3,43 [9] TagHelpersWithPrefix.cshtml)
+ IntermediateToken - (106:3,43 [2] TagHelpersWithPrefix.cshtml) - Html - \n
+ IntermediateToken - (108:4,0 [7] TagHelpersWithPrefix.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml
new file mode 100644
index 0000000000..071122c261
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml
@@ -0,0 +1,19 @@
+@addTagHelper "*, TestAssembly"
+
+@functions {
+ public void RenderTemplate(string title, Func<string, HelperResult> template)
+ {
+ Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");
+ var helperResult = template(title);
+ helperResult.WriteTo(Output, HtmlEncoder);
+ }
+}
+
+<div>
+ @{
+ RenderTemplate(
+ "Template: ",
+ @<div condition="true"><h3>@item</h3><input type="checkbox" checked="true" /></div>);
+ }
+</div>
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.codegen.cs
new file mode 100644
index 0000000000..47937e15b1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.codegen.cs
@@ -0,0 +1,64 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithTemplate_DesignTime
+ {
+ private global::DivTagHelper __DivTagHelper;
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+
+ RenderTemplate(
+ "Template: ",
+
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ }
+ )
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+ );
+
+
+#line default
+#line hidden
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ }
+ #pragma warning restore 1998
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+
+ public void RenderTemplate(string title, Func<string, HelperResult> template)
+ {
+ Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");
+ var helperResult = template(title);
+ helperResult.WriteTo(Output, HtmlEncoder);
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.ir.txt
new file mode 100644
index 0000000000..b472714e8c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.ir.txt
@@ -0,0 +1,57 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithTemplate_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] TagHelpersWithTemplate.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (31:0,31 [4] TagHelpersWithTemplate.cshtml) - Html - \n\n
+ HtmlContent - (316:9,1 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (316:9,1 [4] TagHelpersWithTemplate.cshtml) - Html - \n\n
+ TagHelper - (320:11,0 [179] TagHelpersWithTemplate.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (325:11,5 [6] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (325:11,5 [6] TagHelpersWithTemplate.cshtml) - Html - \n
+ CSharpCode - (333:12,6 [66] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (333:12,6 [66] TagHelpersWithTemplate.cshtml) - CSharp - \n RenderTemplate(\n "Template: ",\n
+ Template - (400:15,13 [82] TagHelpersWithTemplate.cshtml)
+ TagHelper - (400:15,13 [82] TagHelpersWithTemplate.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (422:15,35 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (422:15,35 [4] TagHelpersWithTemplate.cshtml) - Html - <h3>
+ CSharpExpression - (427:15,40 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (427:15,40 [4] TagHelpersWithTemplate.cshtml) - CSharp - item
+ HtmlContent - (431:15,44 [5] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (431:15,44 [5] TagHelpersWithTemplate.cshtml) - Html - </h3>
+ TagHelper - (436:15,49 [40] TagHelpersWithTemplate.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperHtmlAttribute - - type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (449:15,62 [8] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (449:15,62 [8] TagHelpersWithTemplate.cshtml) - Html - checkbox
+ DefaultTagHelperHtmlAttribute - - checked - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (468:15,81 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (468:15,81 [4] TagHelpersWithTemplate.cshtml) - Html - true
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperHtmlAttribute - - condition - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (416:15,29 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (416:15,29 [4] TagHelpersWithTemplate.cshtml) - Html - true
+ DefaultTagHelperExecute -
+ CSharpCode - (482:15,95 [8] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (482:15,95 [8] TagHelpersWithTemplate.cshtml) - CSharp - );\n
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (499:17,6 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (499:17,6 [4] TagHelpersWithTemplate.cshtml) - Html - \n\n
+ CSharpCode - (47:2,12 [268] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (47:2,12 [268] TagHelpersWithTemplate.cshtml) - CSharp - \n public void RenderTemplate(string title, Func<string, HelperResult> template)\n {\n Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");\n var helperResult = template(title);\n helperResult.WriteTo(Output, HtmlEncoder);\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.mappings.txt
new file mode 100644
index 0000000000..7426e542d0
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_DesignTime.mappings.txt
@@ -0,0 +1,47 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml)
+|"*, TestAssembly"|
+Generated Location: (540:12,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (333:12,6 [66] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml)
+|
+ RenderTemplate(
+ "Template: ",
+ |
+Generated Location: (979:24,6 [66] )
+|
+ RenderTemplate(
+ "Template: ",
+ |
+
+Source Location: (427:15,40 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml)
+|item|
+Generated Location: (1287:33,40 [4] )
+|item|
+
+Source Location: (482:15,95 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml)
+|);
+ |
+Generated Location: (1703:42,95 [8] )
+|);
+ |
+
+Source Location: (47:2,12 [268] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml)
+|
+ public void RenderTemplate(string title, Func<string, HelperResult> template)
+ {
+ Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");
+ var helperResult = template(title);
+ helperResult.WriteTo(Output, HtmlEncoder);
+ }
+|
+Generated Location: (1974:51,12 [268] )
+|
+ public void RenderTemplate(string title, Func<string, HelperResult> template)
+ {
+ Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");
+ var helperResult = template(title);
+ helperResult.WriteTo(Output, HtmlEncoder);
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.codegen.cs
new file mode 100644
index 0000000000..a8f6cbf980
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.codegen.cs
@@ -0,0 +1,121 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "d02421b6972074e82cabcfd56c7ab2739d5f3d49"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithTemplate_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"d02421b6972074e82cabcfd56c7ab2739d5f3d49", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithTemplate_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", new global::Microsoft.AspNetCore.Html.HtmlString("checkbox"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("checked", new global::Microsoft.AspNetCore.Html.HtmlString("true"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("condition", new global::Microsoft.AspNetCore.Html.HtmlString("true"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::DivTagHelper __DivTagHelper;
+ private global::InputTagHelper __InputTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("\r\n");
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+
+ RenderTemplate(
+ "Template: ",
+
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("div", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("<h3>");
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral("</h3>");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __InputTagHelper = CreateTagHelper<global::InputTagHelper>();
+ __tagHelperExecutionContext.Add(__InputTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ );
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __tagHelperExecutionContext.Add(__DivTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ PopWriter();
+ }
+ )
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+ );
+
+
+#line default
+#line hidden
+ }
+ );
+ __DivTagHelper = CreateTagHelper<global::DivTagHelper>();
+ __tagHelperExecutionContext.Add(__DivTagHelper);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ }
+ #pragma warning restore 1998
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate.cshtml"
+
+ public void RenderTemplate(string title, Func<string, HelperResult> template)
+ {
+ Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");
+ var helperResult = template(title);
+ helperResult.WriteTo(Output, HtmlEncoder);
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.ir.txt
new file mode 100644
index 0000000000..d53344f511
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithTemplate_Runtime.ir.txt
@@ -0,0 +1,50 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithTemplate_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - type - checkbox - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - checked - true - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - condition - true - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::DivTagHelper - __DivTagHelper
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (33:1,0 [2] TagHelpersWithTemplate.cshtml) - Html - \n
+ HtmlContent - (318:10,0 [2] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (318:10,0 [2] TagHelpersWithTemplate.cshtml) - Html - \n
+ TagHelper - (320:11,0 [179] TagHelpersWithTemplate.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (325:11,5 [2] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (325:11,5 [2] TagHelpersWithTemplate.cshtml) - Html - \n
+ CSharpCode - (327:12,0 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (327:12,0 [4] TagHelpersWithTemplate.cshtml) - CSharp -
+ CSharpCode - (333:12,6 [66] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (333:12,6 [66] TagHelpersWithTemplate.cshtml) - CSharp - \n RenderTemplate(\n "Template: ",\n
+ Template - (400:15,13 [82] TagHelpersWithTemplate.cshtml)
+ TagHelper - (400:15,13 [82] TagHelpersWithTemplate.cshtml) - div - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (422:15,35 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (422:15,35 [4] TagHelpersWithTemplate.cshtml) - Html - <h3>
+ CSharpExpression - (427:15,40 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (427:15,40 [4] TagHelpersWithTemplate.cshtml) - CSharp - item
+ HtmlContent - (431:15,44 [5] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (431:15,44 [5] TagHelpersWithTemplate.cshtml) - Html - </h3>
+ TagHelper - (436:15,49 [40] TagHelpersWithTemplate.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ DefaultTagHelperCreate - - DivTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ CSharpCode - (482:15,95 [8] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (482:15,95 [8] TagHelpersWithTemplate.cshtml) - CSharp - );\n
+ DefaultTagHelperCreate - - DivTagHelper
+ DefaultTagHelperExecute -
+ HtmlContent - (499:17,6 [4] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (499:17,6 [4] TagHelpersWithTemplate.cshtml) - Html - \n\n
+ CSharpCode - (47:2,12 [268] TagHelpersWithTemplate.cshtml)
+ IntermediateToken - (47:2,12 [268] TagHelpersWithTemplate.cshtml) - CSharp - \n public void RenderTemplate(string title, Func<string, HelperResult> template)\n {\n Output.WriteLine("<br /><p><em>Rendering Template:</em></p>");\n var helperResult = template(title);\n helperResult.WriteTo(Output, HtmlEncoder);\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml
new file mode 100644
index 0000000000..1796ed5c04
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml
@@ -0,0 +1,15 @@
+@addTagHelper "*, TestAssembly"
+
+<p
+class
+ =
+"Hello World" age =1337
+ data-content= "@true">Body of Tag</p>
+
+<input type = 'text' data-content= "hello" />
+
+<p age= "1234" data-content
+= 'hello2'></p>
+
+<input type
+ =password data-content =blah/> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..42a22375b7
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.codegen.cs
@@ -0,0 +1,54 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithWeirdlySpacedAttributes_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+ __o = true;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "text";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1234;
+
+#line default
+#line hidden
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __TestNamespace_InputTagHelper.Type = "password";
+ __TestNamespace_InputTagHelper2.Type = __TestNamespace_InputTagHelper.Type;
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..2ada0a9862
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.ir.txt
@@ -0,0 +1,75 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithWeirdlySpacedAttributes_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] TagHelpersWithWeirdlySpacedAttributes.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (31:0,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (35:2,0 [85] TagHelpersWithWeirdlySpacedAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (105:6,25 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (105:6,25 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (54:5,1 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (54:5,1 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - Hello World
+ DefaultTagHelperProperty - (74:5,21 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (74:5,21 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (99:6,19 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (99:6,19 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (120:6,40 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (120:6,40 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (124:8,0 [47] TagHelpersWithWeirdlySpacedAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - text
+ DefaultTagHelperProperty - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - text
+ DefaultTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (162:8,38 [5] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (162:8,38 [5] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - hello
+ DefaultTagHelperExecute -
+ HtmlContent - (171:8,47 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (171:8,47 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (175:10,0 [46] TagHelpersWithWeirdlySpacedAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (186:10,11 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (186:10,11 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - 1234
+ DefaultTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.SingleQuotes
+ HtmlContent - (209:11,3 [6] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (209:11,3 [6] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - hello2
+ DefaultTagHelperExecute -
+ HtmlContent - (221:11,15 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (221:11,15 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (225:13,0 [51] TagHelpersWithWeirdlySpacedAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ DefaultTagHelperProperty - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - type - string TestNamespace.InputTagHelper.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - password
+ DefaultTagHelperProperty - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - type - string TestNamespace.InputTagHelper2.Type - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - password
+ DefaultTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.NoQuotes
+ HtmlContent - (270:14,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (270:14,31 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - blah
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..541fbb7b28
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_DesignTime.mappings.txt
@@ -0,0 +1,20 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml)
+|"*, TestAssembly"|
+Generated Location: (695:13,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (74:5,21 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml)
+|1337|
+Generated Location: (1270:26,33 [4] )
+|1337|
+
+Source Location: (99:6,19 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml)
+|true|
+Generated Location: (1440:31,19 [4] )
+|true|
+
+Source Location: (186:10,11 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml)
+|1234|
+Generated Location: (2076:41,33 [4] )
+|1234|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..b975f6f6ee
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.codegen.cs
@@ -0,0 +1,134 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "a58200cdb2a70e95e4cebb5c830216be0ae4b62c"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithWeirdlySpacedAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"a58200cdb2a70e95e4cebb5c830216be0ae4b62c", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithWeirdlySpacedAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("Hello World"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "text", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("hello"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("hello2"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.SingleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("type", "password", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("data-content", new global::Microsoft.AspNetCore.Html.HtmlString("blah"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.NoQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ private global::TestNamespace.InputTagHelper __TestNamespace_InputTagHelper;
+ private global::TestNamespace.InputTagHelper2 __TestNamespace_InputTagHelper2;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Body of Tag");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ BeginWriteTagHelperAttribute();
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+ Write(true);
+
+#line default
+#line hidden
+ __tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
+ __tagHelperExecutionContext.AddHtmlAttribute("data-content", Html.Raw(__tagHelperStringValueBuffer), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_1.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_1);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_2);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1234;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
+ }
+ );
+ __TestNamespace_InputTagHelper = CreateTagHelper<global::TestNamespace.InputTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper);
+ __TestNamespace_InputTagHelper2 = CreateTagHelper<global::TestNamespace.InputTagHelper2>();
+ __tagHelperExecutionContext.Add(__TestNamespace_InputTagHelper2);
+ __TestNamespace_InputTagHelper.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __TestNamespace_InputTagHelper2.Type = (string)__tagHelperAttribute_4.Value;
+ __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_5);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..e6920b3067
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TagHelpersWithWeirdlySpacedAttributes_Runtime.ir.txt
@@ -0,0 +1,59 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TagHelpersWithWeirdlySpacedAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - Hello World - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - data-content - hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_3 - data-content - hello2 - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_4 - type - password - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_5 - data-content - blah - HtmlAttributeValueStyle.NoQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper - __TestNamespace_InputTagHelper
+ FieldDeclaration - - private - global::TestNamespace.InputTagHelper2 - __TestNamespace_InputTagHelper2
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (33:1,0 [2] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (33:1,0 [2] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n
+ TagHelper - (35:2,0 [85] TagHelpersWithWeirdlySpacedAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (105:6,25 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (105:6,25 [11] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (74:5,21 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (74:5,21 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperHtmlAttribute - - data-content - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (99:6,19 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (99:6,19 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - true
+ DefaultTagHelperExecute -
+ HtmlContent - (120:6,40 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (120:6,40 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (124:8,0 [47] TagHelpersWithWeirdlySpacedAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperProperty - (140:8,16 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - __tagHelperAttribute_1 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
+ HtmlContent - (171:8,47 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (171:8,47 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (175:10,0 [46] TagHelpersWithWeirdlySpacedAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperProperty - (186:10,11 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (186:10,11 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - CSharp - 1234
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_3
+ DefaultTagHelperExecute -
+ HtmlContent - (221:11,15 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml)
+ IntermediateToken - (221:11,15 [4] TagHelpersWithWeirdlySpacedAttributes.cshtml) - Html - \n\n
+ TagHelper - (225:13,0 [51] TagHelpersWithWeirdlySpacedAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper
+ DefaultTagHelperCreate - - TestNamespace.InputTagHelper2
+ PreallocatedTagHelperProperty - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - __tagHelperAttribute_4 - type - Type
+ PreallocatedTagHelperProperty - (247:14,8 [8] TagHelpersWithWeirdlySpacedAttributes.cshtml) - __tagHelperAttribute_4 - type - Type
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_5
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml
new file mode 100644
index 0000000000..467329dc4d
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml
@@ -0,0 +1,53 @@
+@functions {
+ public HelperResult Repeat(int times, Func<int, object> template) {
+ return new HelperResult((writer) => {
+ for(int i = 0; i < times; i++) {
+ ((HelperResult)template(i)).WriteTo(writer);
+ }
+ });
+ }
+}
+
+@{
+ Func<dynamic, object> foo = @<text>This works @item!</text>;
+ @foo("")
+}
+
+@{
+ Func<dynamic, object> bar = @<p class="@item">Hello</p>;
+ @bar("myclass")
+}
+
+<ul>
+@(Repeat(10, @<li>Item #@item</li>))
+</ul>
+
+<p>
+@Repeat(10,
+ @: This is line#@item of markup<br/>
+)
+</p>
+
+<p>
+@Repeat(10,
+ @:: This is line#@item of markup<br />
+)
+</p>
+
+<p>
+@Repeat(10,
+ @::: This is line#@item of markup<br />
+)
+</p>
+
+
+<ul>
+ @Repeat(10, @<li>
+ Item #@item
+ @{var parent = item;}
+ <ul>
+ <li>Child Items... ?</li>
+ @*Repeat(10, @<li>Item #@(parent).@item</li>)*@
+ </ul>
+ </li>)
+</ul> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.codegen.cs
new file mode 100644
index 0000000000..e71dc97f63
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.codegen.cs
@@ -0,0 +1,156 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Templates_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ Func<dynamic, object> foo =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+ }
+ )
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ ;
+
+
+#line default
+#line hidden
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = foo("");
+
+#line default
+#line hidden
+
+
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ Func<dynamic, object> bar =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+ }
+ )
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ ;
+
+
+#line default
+#line hidden
+#line 18 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = bar("myclass");
+
+#line default
+#line hidden
+
+
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = Repeat(10, item => new Template(async(__razor_template_writer) => {
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+#line 32 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+#line 38 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+#line 39 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+#line 45 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+__o = Repeat(10, item => new Template(async(__razor_template_writer) => {
+#line 46 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ __o = item;
+
+#line default
+#line hidden
+#line 47 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ var parent = item;
+
+#line default
+#line hidden
+}
+));
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ public HelperResult Repeat(int times, Func<int, object> template) {
+ return new HelperResult((writer) => {
+ for(int i = 0; i < times; i++) {
+ ((HelperResult)template(i)).WriteTo(writer);
+ }
+ });
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.ir.txt
new file mode 100644
index 0000000000..564759972a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.ir.txt
@@ -0,0 +1,149 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Templates_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (278:8,1 [4] Templates.cshtml)
+ IntermediateToken - (278:8,1 [4] Templates.cshtml) - Html - \n\n
+ CSharpCode - (284:10,2 [34] Templates.cshtml)
+ IntermediateToken - (284:10,2 [34] Templates.cshtml) - CSharp - \n Func<dynamic, object> foo =
+ Template - (325:11,39 [16] Templates.cshtml)
+ HtmlContent - (325:11,39 [11] Templates.cshtml)
+ IntermediateToken - (325:11,39 [11] Templates.cshtml) - Html - This works
+ CSharpExpression - (337:11,51 [4] Templates.cshtml)
+ IntermediateToken - (337:11,51 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (341:11,55 [1] Templates.cshtml)
+ IntermediateToken - (341:11,55 [1] Templates.cshtml) - Html - !
+ CSharpCode - (349:11,63 [7] Templates.cshtml)
+ IntermediateToken - (349:11,63 [7] Templates.cshtml) - CSharp - ;\n
+ CSharpExpression - (357:12,5 [7] Templates.cshtml)
+ IntermediateToken - (357:12,5 [7] Templates.cshtml) - CSharp - foo("")
+ CSharpCode - (364:12,12 [2] Templates.cshtml)
+ IntermediateToken - (364:12,12 [2] Templates.cshtml) - CSharp - \n
+ HtmlContent - (369:14,0 [2] Templates.cshtml)
+ IntermediateToken - (369:14,0 [2] Templates.cshtml) - Html - \n
+ CSharpCode - (373:15,2 [35] Templates.cshtml)
+ IntermediateToken - (373:15,2 [35] Templates.cshtml) - CSharp - \n Func<dynamic, object> bar =
+ Template - (409:16,33 [26] Templates.cshtml)
+ HtmlContent - (409:16,33 [2] Templates.cshtml)
+ IntermediateToken - (409:16,33 [2] Templates.cshtml) - Html - <p
+ HtmlAttribute - (411:16,35 [14] Templates.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (419:16,43 [5] Templates.cshtml) -
+ IntermediateToken - (420:16,44 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (425:16,49 [10] Templates.cshtml)
+ IntermediateToken - (425:16,49 [1] Templates.cshtml) - Html - >
+ IntermediateToken - (426:16,50 [5] Templates.cshtml) - Html - Hello
+ IntermediateToken - (431:16,55 [4] Templates.cshtml) - Html - </p>
+ CSharpCode - (435:16,59 [7] Templates.cshtml)
+ IntermediateToken - (435:16,59 [7] Templates.cshtml) - CSharp - ;\n
+ CSharpExpression - (443:17,5 [14] Templates.cshtml)
+ IntermediateToken - (443:17,5 [14] Templates.cshtml) - CSharp - bar("myclass")
+ CSharpCode - (457:17,19 [2] Templates.cshtml)
+ IntermediateToken - (457:17,19 [2] Templates.cshtml) - CSharp - \n
+ HtmlContent - (462:19,0 [8] Templates.cshtml)
+ IntermediateToken - (462:19,0 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (464:20,0 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (468:20,4 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (472:21,2 [31] Templates.cshtml)
+ IntermediateToken - (472:21,2 [11] Templates.cshtml) - CSharp - Repeat(10,
+ Template - (484:21,14 [19] Templates.cshtml)
+ HtmlContent - (484:21,14 [10] Templates.cshtml)
+ IntermediateToken - (484:21,14 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (488:21,18 [6] Templates.cshtml) - Html - Item #
+ CSharpExpression - (495:21,25 [4] Templates.cshtml)
+ IntermediateToken - (495:21,25 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (499:21,29 [5] Templates.cshtml)
+ IntermediateToken - (499:21,29 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (504:21,34 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (506:21,36 [16] Templates.cshtml)
+ IntermediateToken - (506:21,36 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (508:22,0 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (513:22,5 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (517:24,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (520:24,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (523:25,1 [52] Templates.cshtml)
+ IntermediateToken - (523:25,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (541:26,6 [35] Templates.cshtml)
+ HtmlContent - (541:26,6 [14] Templates.cshtml)
+ IntermediateToken - (541:26,6 [14] Templates.cshtml) - Html - This is line#
+ CSharpExpression - (556:26,21 [4] Templates.cshtml)
+ IntermediateToken - (556:26,21 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (560:26,25 [17] Templates.cshtml)
+ IntermediateToken - (560:26,25 [17] Templates.cshtml) - Html - of markup<br/>\n
+ IntermediateToken - (577:27,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (578:27,1 [15] Templates.cshtml)
+ IntermediateToken - (578:27,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (580:28,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (584:28,4 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (588:30,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (591:30,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (594:31,1 [54] Templates.cshtml)
+ IntermediateToken - (594:31,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (612:32,6 [37] Templates.cshtml)
+ HtmlContent - (612:32,6 [15] Templates.cshtml)
+ IntermediateToken - (612:32,6 [15] Templates.cshtml) - Html - : This is line#
+ CSharpExpression - (628:32,22 [4] Templates.cshtml)
+ IntermediateToken - (628:32,22 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (632:32,26 [18] Templates.cshtml)
+ IntermediateToken - (632:32,26 [18] Templates.cshtml) - Html - of markup<br />\n
+ IntermediateToken - (650:33,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (651:33,1 [15] Templates.cshtml)
+ IntermediateToken - (651:33,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (653:34,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (657:34,4 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (661:36,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (664:36,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (667:37,1 [55] Templates.cshtml)
+ IntermediateToken - (667:37,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (685:38,6 [38] Templates.cshtml)
+ HtmlContent - (685:38,6 [16] Templates.cshtml)
+ IntermediateToken - (685:38,6 [16] Templates.cshtml) - Html - :: This is line#
+ CSharpExpression - (702:38,23 [4] Templates.cshtml)
+ IntermediateToken - (702:38,23 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (706:38,27 [18] Templates.cshtml)
+ IntermediateToken - (706:38,27 [18] Templates.cshtml) - Html - of markup<br />\n
+ IntermediateToken - (724:39,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (725:39,1 [22] Templates.cshtml)
+ IntermediateToken - (725:39,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (727:40,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (731:40,4 [6] Templates.cshtml) - Html - \n\n\n
+ IntermediateToken - (737:43,0 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (741:43,4 [6] Templates.cshtml) - Html - \n
+ CSharpExpression - (748:44,5 [141] Templates.cshtml)
+ IntermediateToken - (748:44,5 [11] Templates.cshtml) - CSharp - Repeat(10,
+ Template - (760:44,17 [129] Templates.cshtml)
+ HtmlContent - (760:44,17 [20] Templates.cshtml)
+ IntermediateToken - (760:44,17 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (764:44,21 [16] Templates.cshtml) - Html - \n Item #
+ CSharpExpression - (781:45,15 [4] Templates.cshtml)
+ IntermediateToken - (781:45,15 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (785:45,19 [10] Templates.cshtml)
+ IntermediateToken - (785:45,19 [10] Templates.cshtml) - Html - \n
+ CSharpCode - (797:46,10 [18] Templates.cshtml)
+ IntermediateToken - (797:46,10 [18] Templates.cshtml) - CSharp - var parent = item;
+ HtmlContent - (818:47,0 [53] Templates.cshtml)
+ IntermediateToken - (818:47,0 [8] Templates.cshtml) - Html -
+ IntermediateToken - (826:47,8 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (830:47,12 [14] Templates.cshtml) - Html - \n
+ IntermediateToken - (844:48,12 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (848:48,16 [16] Templates.cshtml) - Html - Child Items... ?
+ IntermediateToken - (864:48,32 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (869:48,37 [2] Templates.cshtml) - Html - \n
+ HtmlContent - (932:50,0 [24] Templates.cshtml)
+ IntermediateToken - (932:50,0 [8] Templates.cshtml) - Html -
+ IntermediateToken - (940:50,8 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (945:50,13 [6] Templates.cshtml) - Html - \n
+ IntermediateToken - (951:51,4 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (956:51,9 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (957:51,10 [8] Templates.cshtml)
+ IntermediateToken - (957:51,10 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (959:52,0 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (964:52,5 [1] Templates.cshtml) - Html -
+ CSharpCode - (12:0,12 [265] Templates.cshtml)
+ IntermediateToken - (12:0,12 [265] Templates.cshtml) - CSharp - \n public HelperResult Repeat(int times, Func<int, object> template) {\n return new HelperResult((writer) => {\n for(int i = 0; i < times; i++) {\n ((HelperResult)template(i)).WriteTo(writer);\n }\n });\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.mappings.txt
new file mode 100644
index 0000000000..3c35d4c99a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_DesignTime.mappings.txt
@@ -0,0 +1,169 @@
+Source Location: (284:10,2 [34] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|
+ Func<dynamic, object> foo = |
+Generated Location: (720:18,2 [34] )
+|
+ Func<dynamic, object> foo = |
+
+Source Location: (337:11,51 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (994:25,51 [4] )
+|item|
+
+Source Location: (349:11,63 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|;
+ |
+Generated Location: (1211:32,63 [7] )
+|;
+ |
+
+Source Location: (357:12,5 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|foo("")|
+Generated Location: (1343:38,6 [7] )
+|foo("")|
+
+Source Location: (364:12,12 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|
+|
+Generated Location: (1408:42,24 [2] )
+|
+|
+
+Source Location: (373:15,2 [35] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|
+ Func<dynamic, object> bar = |
+Generated Location: (1500:45,2 [35] )
+|
+ Func<dynamic, object> bar = |
+
+Source Location: (420:16,44 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (1768:52,44 [4] )
+|item|
+
+Source Location: (435:16,59 [7] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|;
+ |
+Generated Location: (1981:59,59 [7] )
+|;
+ |
+
+Source Location: (443:17,5 [14] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|bar("myclass")|
+Generated Location: (2113:65,6 [14] )
+|bar("myclass")|
+
+Source Location: (457:17,19 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|
+|
+Generated Location: (2192:69,31 [2] )
+|
+|
+
+Source Location: (472:21,2 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|Repeat(10, |
+Generated Location: (2288:72,6 [11] )
+|Repeat(10, |
+
+Source Location: (495:21,25 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (2468:74,25 [4] )
+|item|
+
+Source Location: (504:21,34 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|)|
+Generated Location: (2510:79,1 [1] )
+|)|
+
+Source Location: (523:25,1 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|Repeat(10,
+ |
+Generated Location: (2637:84,6 [16] )
+|Repeat(10,
+ |
+
+Source Location: (556:26,21 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (2818:87,21 [4] )
+|item|
+
+Source Location: (577:27,0 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|)|
+Generated Location: (2860:92,1 [1] )
+|)|
+
+Source Location: (594:31,1 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|Repeat(10,
+ |
+Generated Location: (2987:97,6 [16] )
+|Repeat(10,
+ |
+
+Source Location: (628:32,22 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (3169:100,22 [4] )
+|item|
+
+Source Location: (650:33,0 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|)|
+Generated Location: (3211:105,1 [1] )
+|)|
+
+Source Location: (667:37,1 [16] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|Repeat(10,
+ |
+Generated Location: (3338:110,6 [16] )
+|Repeat(10,
+ |
+
+Source Location: (702:38,23 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (3521:113,23 [4] )
+|item|
+
+Source Location: (724:39,0 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|)|
+Generated Location: (3563:118,1 [1] )
+|)|
+
+Source Location: (748:44,5 [11] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|Repeat(10, |
+Generated Location: (3690:123,6 [11] )
+|Repeat(10, |
+
+Source Location: (781:45,15 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|item|
+Generated Location: (3860:125,15 [4] )
+|item|
+
+Source Location: (797:46,10 [18] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|var parent = item;|
+Generated Location: (3994:130,10 [18] )
+|var parent = item;|
+
+Source Location: (956:51,9 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|)|
+Generated Location: (4049:135,1 [1] )
+|)|
+
+Source Location: (12:0,12 [265] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml)
+|
+ public HelperResult Repeat(int times, Func<int, object> template) {
+ return new HelperResult((writer) => {
+ for(int i = 0; i < times; i++) {
+ ((HelperResult)template(i)).WriteTo(writer);
+ }
+ });
+ }
+|
+Generated Location: (4230:142,12 [265] )
+|
+ public HelperResult Repeat(int times, Func<int, object> template) {
+ return new HelperResult((writer) => {
+ for(int i = 0; i < times; i++) {
+ ((HelperResult)template(i)).WriteTo(writer);
+ }
+ });
+ }
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.codegen.cs
new file mode 100644
index 0000000000..050a2efb18
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.codegen.cs
@@ -0,0 +1,188 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "488aa2f21a6d3e3c761871ec0bf2f295695db71a"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Templates_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"488aa2f21a6d3e3c761871ec0bf2f295695db71a", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Templates_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ Func<dynamic, object> foo =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("This works ");
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral("!");
+ PopWriter();
+ }
+ )
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ ;
+
+
+#line default
+#line hidden
+#line 13 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(foo(""));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 16 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ Func<dynamic, object> bar =
+
+#line default
+#line hidden
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("<p");
+ BeginWriteAttribute("class", " class=\"", 411, "\"", 424, 1);
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+WriteAttributeValue("", 419, item, 419, 5, false);
+
+#line default
+#line hidden
+ EndWriteAttribute();
+ WriteLiteral(">Hello</p>");
+ PopWriter();
+ }
+ )
+#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ ;
+
+
+#line default
+#line hidden
+#line 18 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(bar("myclass"));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n<ul>\r\n");
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(Repeat(10, item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("<li>Item #");
+#line 22 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral("</li>");
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n</ul>\r\n\r\n<p>\r\n");
+#line 26 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral(" This is line#");
+#line 27 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral(" of markup<br/>\r\n");
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n</p>\r\n\r\n<p>\r\n");
+#line 32 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral(": This is line#");
+#line 33 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral(" of markup<br />\r\n");
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n</p>\r\n\r\n<p>\r\n");
+#line 38 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral(":: This is line#");
+#line 39 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral(" of markup<br />\r\n");
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n</p>\r\n\r\n\r\n<ul>\r\n ");
+#line 45 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+Write(Repeat(10, item => new Template(async(__razor_template_writer) => {
+ PushWriter(__razor_template_writer);
+ WriteLiteral("<li>\r\n Item #");
+#line 46 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ Write(item);
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+#line 47 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+ var parent = item;
+
+#line default
+#line hidden
+ WriteLiteral(" <ul>\r\n <li>Child Items... ?</li>\r\n");
+ WriteLiteral(" </ul>\r\n </li>");
+ PopWriter();
+}
+)));
+
+#line default
+#line hidden
+ WriteLiteral("\r\n</ul> ");
+ }
+ #pragma warning restore 1998
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates.cshtml"
+
+ public HelperResult Repeat(int times, Func<int, object> template) {
+ return new HelperResult((writer) => {
+ for(int i = 0; i < times; i++) {
+ ((HelperResult)template(i)).WriteTo(writer);
+ }
+ });
+ }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.ir.txt
new file mode 100644
index 0000000000..4416a51d48
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Templates_Runtime.ir.txt
@@ -0,0 +1,147 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Templates_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (280:9,0 [2] Templates.cshtml)
+ IntermediateToken - (280:9,0 [2] Templates.cshtml) - Html - \n
+ CSharpCode - (284:10,2 [34] Templates.cshtml)
+ IntermediateToken - (284:10,2 [34] Templates.cshtml) - CSharp - \n Func<dynamic, object> foo =
+ Template - (325:11,39 [16] Templates.cshtml)
+ HtmlContent - (325:11,39 [11] Templates.cshtml)
+ IntermediateToken - (325:11,39 [11] Templates.cshtml) - Html - This works
+ CSharpExpression - (337:11,51 [4] Templates.cshtml)
+ IntermediateToken - (337:11,51 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (341:11,55 [1] Templates.cshtml)
+ IntermediateToken - (341:11,55 [1] Templates.cshtml) - Html - !
+ CSharpCode - (349:11,63 [7] Templates.cshtml)
+ IntermediateToken - (349:11,63 [7] Templates.cshtml) - CSharp - ;\n
+ CSharpExpression - (357:12,5 [7] Templates.cshtml)
+ IntermediateToken - (357:12,5 [7] Templates.cshtml) - CSharp - foo("")
+ CSharpCode - (364:12,12 [2] Templates.cshtml)
+ IntermediateToken - (364:12,12 [2] Templates.cshtml) - CSharp - \n
+ HtmlContent - (369:14,0 [2] Templates.cshtml)
+ IntermediateToken - (369:14,0 [2] Templates.cshtml) - Html - \n
+ CSharpCode - (373:15,2 [35] Templates.cshtml)
+ IntermediateToken - (373:15,2 [35] Templates.cshtml) - CSharp - \n Func<dynamic, object> bar =
+ Template - (409:16,33 [26] Templates.cshtml)
+ HtmlContent - (409:16,33 [2] Templates.cshtml)
+ IntermediateToken - (409:16,33 [2] Templates.cshtml) - Html - <p
+ HtmlAttribute - (411:16,35 [14] Templates.cshtml) - class=" - "
+ CSharpExpressionAttributeValue - (419:16,43 [5] Templates.cshtml) -
+ IntermediateToken - (420:16,44 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (425:16,49 [10] Templates.cshtml)
+ IntermediateToken - (425:16,49 [1] Templates.cshtml) - Html - >
+ IntermediateToken - (426:16,50 [5] Templates.cshtml) - Html - Hello
+ IntermediateToken - (431:16,55 [4] Templates.cshtml) - Html - </p>
+ CSharpCode - (435:16,59 [7] Templates.cshtml)
+ IntermediateToken - (435:16,59 [7] Templates.cshtml) - CSharp - ;\n
+ CSharpExpression - (443:17,5 [14] Templates.cshtml)
+ IntermediateToken - (443:17,5 [14] Templates.cshtml) - CSharp - bar("myclass")
+ CSharpCode - (457:17,19 [2] Templates.cshtml)
+ IntermediateToken - (457:17,19 [2] Templates.cshtml) - CSharp - \n
+ HtmlContent - (462:19,0 [8] Templates.cshtml)
+ IntermediateToken - (462:19,0 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (464:20,0 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (468:20,4 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (472:21,2 [31] Templates.cshtml)
+ IntermediateToken - (472:21,2 [11] Templates.cshtml) - CSharp - Repeat(10,
+ Template - (484:21,14 [19] Templates.cshtml)
+ HtmlContent - (484:21,14 [10] Templates.cshtml)
+ IntermediateToken - (484:21,14 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (488:21,18 [6] Templates.cshtml) - Html - Item #
+ CSharpExpression - (495:21,25 [4] Templates.cshtml)
+ IntermediateToken - (495:21,25 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (499:21,29 [5] Templates.cshtml)
+ IntermediateToken - (499:21,29 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (504:21,34 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (506:21,36 [16] Templates.cshtml)
+ IntermediateToken - (506:21,36 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (508:22,0 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (513:22,5 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (517:24,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (520:24,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (523:25,1 [52] Templates.cshtml)
+ IntermediateToken - (523:25,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (541:26,6 [35] Templates.cshtml)
+ HtmlContent - (541:26,6 [14] Templates.cshtml)
+ IntermediateToken - (541:26,6 [14] Templates.cshtml) - Html - This is line#
+ CSharpExpression - (556:26,21 [4] Templates.cshtml)
+ IntermediateToken - (556:26,21 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (560:26,25 [17] Templates.cshtml)
+ IntermediateToken - (560:26,25 [17] Templates.cshtml) - Html - of markup<br/>\n
+ IntermediateToken - (577:27,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (578:27,1 [15] Templates.cshtml)
+ IntermediateToken - (578:27,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (580:28,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (584:28,4 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (588:30,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (591:30,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (594:31,1 [54] Templates.cshtml)
+ IntermediateToken - (594:31,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (612:32,6 [37] Templates.cshtml)
+ HtmlContent - (612:32,6 [15] Templates.cshtml)
+ IntermediateToken - (612:32,6 [15] Templates.cshtml) - Html - : This is line#
+ CSharpExpression - (628:32,22 [4] Templates.cshtml)
+ IntermediateToken - (628:32,22 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (632:32,26 [18] Templates.cshtml)
+ IntermediateToken - (632:32,26 [18] Templates.cshtml) - Html - of markup<br />\n
+ IntermediateToken - (650:33,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (651:33,1 [15] Templates.cshtml)
+ IntermediateToken - (651:33,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (653:34,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (657:34,4 [4] Templates.cshtml) - Html - \n\n
+ IntermediateToken - (661:36,0 [3] Templates.cshtml) - Html - <p>
+ IntermediateToken - (664:36,3 [2] Templates.cshtml) - Html - \n
+ CSharpExpression - (667:37,1 [55] Templates.cshtml)
+ IntermediateToken - (667:37,1 [16] Templates.cshtml) - CSharp - Repeat(10,\n
+ Template - (685:38,6 [38] Templates.cshtml)
+ HtmlContent - (685:38,6 [16] Templates.cshtml)
+ IntermediateToken - (685:38,6 [16] Templates.cshtml) - Html - :: This is line#
+ CSharpExpression - (702:38,23 [4] Templates.cshtml)
+ IntermediateToken - (702:38,23 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (706:38,27 [18] Templates.cshtml)
+ IntermediateToken - (706:38,27 [18] Templates.cshtml) - Html - of markup<br />\n
+ IntermediateToken - (724:39,0 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (725:39,1 [22] Templates.cshtml)
+ IntermediateToken - (725:39,1 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (727:40,0 [4] Templates.cshtml) - Html - </p>
+ IntermediateToken - (731:40,4 [6] Templates.cshtml) - Html - \n\n\n
+ IntermediateToken - (737:43,0 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (741:43,4 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (743:44,0 [4] Templates.cshtml) - Html -
+ CSharpExpression - (748:44,5 [141] Templates.cshtml)
+ IntermediateToken - (748:44,5 [11] Templates.cshtml) - CSharp - Repeat(10,
+ Template - (760:44,17 [129] Templates.cshtml)
+ HtmlContent - (760:44,17 [20] Templates.cshtml)
+ IntermediateToken - (760:44,17 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (764:44,21 [16] Templates.cshtml) - Html - \n Item #
+ CSharpExpression - (781:45,15 [4] Templates.cshtml)
+ IntermediateToken - (781:45,15 [4] Templates.cshtml) - CSharp - item
+ HtmlContent - (785:45,19 [2] Templates.cshtml)
+ IntermediateToken - (785:45,19 [2] Templates.cshtml) - Html - \n
+ CSharpCode - (787:46,0 [8] Templates.cshtml)
+ IntermediateToken - (787:46,0 [8] Templates.cshtml) - CSharp -
+ CSharpCode - (797:46,10 [18] Templates.cshtml)
+ IntermediateToken - (797:46,10 [18] Templates.cshtml) - CSharp - var parent = item;
+ HtmlContent - (818:47,0 [53] Templates.cshtml)
+ IntermediateToken - (818:47,0 [8] Templates.cshtml) - Html -
+ IntermediateToken - (826:47,8 [4] Templates.cshtml) - Html - <ul>
+ IntermediateToken - (830:47,12 [14] Templates.cshtml) - Html - \n
+ IntermediateToken - (844:48,12 [4] Templates.cshtml) - Html - <li>
+ IntermediateToken - (848:48,16 [16] Templates.cshtml) - Html - Child Items... ?
+ IntermediateToken - (864:48,32 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (869:48,37 [2] Templates.cshtml) - Html - \n
+ HtmlContent - (932:50,0 [24] Templates.cshtml)
+ IntermediateToken - (932:50,0 [8] Templates.cshtml) - Html -
+ IntermediateToken - (940:50,8 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (945:50,13 [6] Templates.cshtml) - Html - \n
+ IntermediateToken - (951:51,4 [5] Templates.cshtml) - Html - </li>
+ IntermediateToken - (956:51,9 [1] Templates.cshtml) - CSharp - )
+ HtmlContent - (957:51,10 [8] Templates.cshtml)
+ IntermediateToken - (957:51,10 [2] Templates.cshtml) - Html - \n
+ IntermediateToken - (959:52,0 [5] Templates.cshtml) - Html - </ul>
+ IntermediateToken - (964:52,5 [1] Templates.cshtml) - Html -
+ CSharpCode - (12:0,12 [265] Templates.cshtml)
+ IntermediateToken - (12:0,12 [265] Templates.cshtml) - CSharp - \n public HelperResult Repeat(int times, Func<int, object> template) {\n return new HelperResult((writer) => {\n for(int i = 0; i < times; i++) {\n ((HelperResult)template(i)).WriteTo(writer);\n }\n });\n }\n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml
new file mode 100644
index 0000000000..b73f2c01fa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml
@@ -0,0 +1,12 @@
+@addTagHelper "*, TestAssembly"
+@{
+ var @class = "container-fluid";
+ var @int = 1;
+}
+
+<p class="@class" age="1337">Body of Tag</p>
+<p class="@(@class)" age="42"></p>
+<p class="test" age="42 + @int"></p>
+<p class="test" age="@int"></p>
+<p class="test" age="@(@int)"></p>
+<p class="custom-@(@class)" age="4 * @(@int + 2)"></p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.codegen.cs
new file mode 100644
index 0000000000..f4215d9483
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.codegen.cs
@@ -0,0 +1,80 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TransitionsInTagHelperAttributes_DesignTime
+ {
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+
+ var @class = "container-fluid";
+ var @int = 1;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+ __o = @class;
+
+#line default
+#line hidden
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 42;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 42 + @int;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = int;
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = (@int);
+
+#line default
+#line hidden
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+ __o = @class;
+
+#line default
+#line hidden
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 4 * @(@int + 2);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.diagnostics.txt
new file mode 100644
index 0000000000..cc0379e358
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml(7,12): Error RZ1007: "class" is a reserved word and cannot be used in implicit expressions. An explicit expression ("@()") must be used.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.ir.txt
new file mode 100644
index 0000000000..e0dcc96a1c
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.ir.txt
@@ -0,0 +1,105 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TransitionsInTagHelperAttributes_DesignTime - -
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [17] TransitionsInTagHelperAttributes.cshtml) - "*, TestAssembly"
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:0,31 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (31:0,31 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ CSharpCode - (35:1,2 [59] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (35:1,2 [59] TransitionsInTagHelperAttributes.cshtml) - CSharp - \n var @class = "container-fluid";\n var @int = 1;\n
+ HtmlContent - (97:5,0 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (97:5,0 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (99:6,0 [44] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (128:6,29 [11] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (128:6,29 [11] TransitionsInTagHelperAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (109:6,10 [6] TransitionsInTagHelperAttributes.cshtml) -
+ DefaultTagHelperProperty - (122:6,23 [4] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (122:6,23 [4] TransitionsInTagHelperAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
+ HtmlContent - (143:6,44 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (143:6,44 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (145:7,0 [34] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (155:7,10 [9] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (157:7,12 [6] TransitionsInTagHelperAttributes.cshtml) - CSharp - @class
+ DefaultTagHelperProperty - (171:7,26 [2] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (171:7,26 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - 42
+ DefaultTagHelperExecute -
+ HtmlContent - (179:7,34 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (179:7,34 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (181:8,0 [36] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (191:8,10 [4] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (191:8,10 [4] TransitionsInTagHelperAttributes.cshtml) - Html - test
+ DefaultTagHelperProperty - (202:8,21 [9] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (202:8,21 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - 42
+ IntermediateToken - (204:8,23 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - +
+ IntermediateToken - (206:8,25 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp -
+ CSharpExpression - (207:8,26 [4] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (207:8,26 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - @
+ IntermediateToken - (208:8,27 [3] TransitionsInTagHelperAttributes.cshtml) - CSharp - int
+ DefaultTagHelperExecute -
+ HtmlContent - (217:8,36 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (217:8,36 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (219:9,0 [31] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (229:9,10 [4] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (229:9,10 [4] TransitionsInTagHelperAttributes.cshtml) - Html - test
+ DefaultTagHelperProperty - (240:9,21 [4] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (241:9,22 [3] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (241:9,22 [3] TransitionsInTagHelperAttributes.cshtml) - CSharp - int
+ DefaultTagHelperExecute -
+ HtmlContent - (250:9,31 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (250:9,31 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (252:10,0 [34] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlContent - (262:10,10 [4] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (262:10,10 [4] TransitionsInTagHelperAttributes.cshtml) - Html - test
+ DefaultTagHelperProperty - (273:10,21 [7] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (274:10,22 [6] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (274:10,22 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - (
+ IntermediateToken - (275:10,23 [4] TransitionsInTagHelperAttributes.cshtml) - CSharp - @int
+ IntermediateToken - (279:10,27 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (286:10,34 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (286:10,34 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (288:11,0 [54] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (298:11,10 [7] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (298:11,10 [7] TransitionsInTagHelperAttributes.cshtml) - Html - custom-
+ CSharpExpressionAttributeValue - (305:11,17 [9] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (307:11,19 [6] TransitionsInTagHelperAttributes.cshtml) - CSharp - @class
+ DefaultTagHelperProperty - (321:11,33 [15] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (321:11,33 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - 4
+ IntermediateToken - (322:11,34 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - *
+ IntermediateToken - (324:11,36 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp -
+ CSharpExpression - (325:11,37 [11] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (325:11,37 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - @
+ IntermediateToken - (326:11,38 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - (
+ IntermediateToken - (327:11,39 [8] TransitionsInTagHelperAttributes.cshtml) - CSharp - @int + 2
+ IntermediateToken - (335:11,47 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (342:11,54 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (342:11,54 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.mappings.txt
new file mode 100644
index 0000000000..8a511b7839
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_DesignTime.mappings.txt
@@ -0,0 +1,116 @@
+Source Location: (14:0,14 [17] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|"*, TestAssembly"|
+Generated Location: (516:11,37 [17] )
+|"*, TestAssembly"|
+
+Source Location: (35:1,2 [59] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|
+ var @class = "container-fluid";
+ var @int = 1;
+|
+Generated Location: (960:23,2 [59] )
+|
+ var @class = "container-fluid";
+ var @int = 1;
+|
+
+Source Location: (122:6,23 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|1337|
+Generated Location: (1286:31,33 [4] )
+|1337|
+
+Source Location: (157:7,12 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@class|
+Generated Location: (1539:37,12 [6] )
+|@class|
+
+Source Location: (171:7,26 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|42|
+Generated Location: (1720:42,33 [2] )
+|42|
+
+Source Location: (202:8,21 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|42|
+Generated Location: (1992:48,33 [2] )
+|42|
+
+Source Location: (204:8,23 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+| +|
+Generated Location: (1994:48,35 [2] )
+| +|
+
+Source Location: (206:8,25 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+| |
+Generated Location: (1996:48,37 [1] )
+| |
+
+Source Location: (207:8,26 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@|
+Generated Location: (1997:48,38 [1] )
+|@|
+
+Source Location: (208:8,27 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|int|
+Generated Location: (1998:48,39 [3] )
+|int|
+
+Source Location: (241:9,22 [3] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|int|
+Generated Location: (2272:54,33 [3] )
+|int|
+
+Source Location: (274:10,22 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|(|
+Generated Location: (2546:60,33 [1] )
+|(|
+
+Source Location: (275:10,23 [4] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@int|
+Generated Location: (2547:60,34 [4] )
+|@int|
+
+Source Location: (279:10,27 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|)|
+Generated Location: (2551:60,38 [1] )
+|)|
+
+Source Location: (307:11,19 [6] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@class|
+Generated Location: (2809:66,19 [6] )
+|@class|
+
+Source Location: (321:11,33 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|4|
+Generated Location: (2991:71,33 [1] )
+|4|
+
+Source Location: (322:11,34 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+| *|
+Generated Location: (2992:71,34 [2] )
+| *|
+
+Source Location: (324:11,36 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+| |
+Generated Location: (2994:71,36 [1] )
+| |
+
+Source Location: (325:11,37 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@|
+Generated Location: (2995:71,37 [1] )
+|@|
+
+Source Location: (326:11,38 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|(|
+Generated Location: (2996:71,38 [1] )
+|(|
+
+Source Location: (327:11,39 [8] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|@int + 2|
+Generated Location: (2997:71,39 [8] )
+|@int + 2|
+
+Source Location: (335:11,47 [1] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml)
+|)|
+Generated Location: (3005:71,47 [1] )
+|)|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.codegen.cs
new file mode 100644
index 0000000000..998715b478
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.codegen.cs
@@ -0,0 +1,186 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f9794a93d1ce05bf71080dc33a3e83b16dbce225"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TransitionsInTagHelperAttributes_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"f9794a93d1ce05bf71080dc33a3e83b16dbce225", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TransitionsInTagHelperAttributes_Runtime
+ {
+ private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("test"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ #line hidden
+ #pragma warning disable 0169
+ private string __tagHelperStringValueBuffer;
+ #pragma warning restore 0169
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
+ private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
+ {
+ get
+ {
+ if (__backed__tagHelperScopeManager == null)
+ {
+ __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
+ }
+ return __backed__tagHelperScopeManager;
+ }
+ }
+ private global::TestNamespace.PTagHelper __TestNamespace_PTagHelper;
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+
+ var @class = "container-fluid";
+ var @int = 1;
+
+#line default
+#line hidden
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ WriteLiteral("Body of Tag");
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 1, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 109, new Microsoft.AspNetCore.Mvc.Razor.HelperResult(async(__razor_attribute_value_writer) => {
+ PushWriter(__razor_attribute_value_writer);
+ PopWriter();
+ }
+ ), 109, 6, false);
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 1337;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 1, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+AddHtmlAttributeValue("", 155, @class, 155, 9, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+#line 8 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 42;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 42 + @int;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = int;
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
+#line 11 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = (@int);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
+ }
+ );
+ __TestNamespace_PTagHelper = CreateTagHelper<global::TestNamespace.PTagHelper>();
+ __tagHelperExecutionContext.Add(__TestNamespace_PTagHelper);
+ BeginAddHtmlAttributeValues(__tagHelperExecutionContext, "class", 2, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ AddHtmlAttributeValue("", 298, "custom-", 298, 7, true);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+AddHtmlAttributeValue("", 305, @class, 305, 9, false);
+
+#line default
+#line hidden
+ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
+#line 12 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml"
+__TestNamespace_PTagHelper.Age = 4 * @(@int + 2);
+
+#line default
+#line hidden
+ __tagHelperExecutionContext.AddTagHelperAttribute("age", __TestNamespace_PTagHelper.Age, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
+ await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
+ if (!__tagHelperExecutionContext.Output.IsContentModified)
+ {
+ await __tagHelperExecutionContext.SetOutputContentAsync();
+ }
+ Write(__tagHelperExecutionContext.Output);
+ __tagHelperExecutionContext = __tagHelperScopeManager.End();
+ WriteLiteral("\r\n");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.diagnostics.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.diagnostics.txt
new file mode 100644
index 0000000000..cc0379e358
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.diagnostics.txt
@@ -0,0 +1 @@
+TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes.cshtml(7,12): Error RZ1007: "class" is a reserved word and cannot be used in implicit expressions. An explicit expression ("@()") must be used.
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.ir.txt
new file mode 100644
index 0000000000..6a6678ed86
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/TransitionsInTagHelperAttributes_Runtime.ir.txt
@@ -0,0 +1,92 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_TransitionsInTagHelperAttributes_Runtime - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - class - test - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::TestNamespace.PTagHelper - __TestNamespace_PTagHelper
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (35:1,2 [59] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (35:1,2 [59] TransitionsInTagHelperAttributes.cshtml) - CSharp - \n var @class = "container-fluid";\n var @int = 1;\n
+ HtmlContent - (97:5,0 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (97:5,0 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (99:6,0 [44] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (128:6,29 [11] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (128:6,29 [11] TransitionsInTagHelperAttributes.cshtml) - Html - Body of Tag
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpCodeAttributeValue - (109:6,10 [6] TransitionsInTagHelperAttributes.cshtml) -
+ DefaultTagHelperProperty - (122:6,23 [4] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (122:6,23 [4] TransitionsInTagHelperAttributes.cshtml) - CSharp - 1337
+ DefaultTagHelperExecute -
+ HtmlContent - (143:6,44 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (143:6,44 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (145:7,0 [34] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpressionAttributeValue - (155:7,10 [9] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (157:7,12 [6] TransitionsInTagHelperAttributes.cshtml) - CSharp - @class
+ DefaultTagHelperProperty - (171:7,26 [2] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (171:7,26 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - 42
+ DefaultTagHelperExecute -
+ HtmlContent - (179:7,34 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (179:7,34 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (181:8,0 [36] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (202:8,21 [9] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (202:8,21 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - 42
+ IntermediateToken - (204:8,23 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - +
+ IntermediateToken - (206:8,25 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp -
+ CSharpExpression - (207:8,26 [4] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (207:8,26 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - @
+ IntermediateToken - (208:8,27 [3] TransitionsInTagHelperAttributes.cshtml) - CSharp - int
+ DefaultTagHelperExecute -
+ HtmlContent - (217:8,36 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (217:8,36 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (219:9,0 [31] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (240:9,21 [4] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (241:9,22 [3] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (241:9,22 [3] TransitionsInTagHelperAttributes.cshtml) - CSharp - int
+ DefaultTagHelperExecute -
+ HtmlContent - (250:9,31 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (250:9,31 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (252:10,0 [34] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperProperty - (273:10,21 [7] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (274:10,22 [6] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (274:10,22 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - (
+ IntermediateToken - (275:10,23 [4] TransitionsInTagHelperAttributes.cshtml) - CSharp - @int
+ IntermediateToken - (279:10,27 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (286:10,34 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (286:10,34 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
+ TagHelper - (288:11,0 [54] TransitionsInTagHelperAttributes.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - TestNamespace.PTagHelper
+ DefaultTagHelperHtmlAttribute - - class - HtmlAttributeValueStyle.DoubleQuotes
+ HtmlAttributeValue - (298:11,10 [7] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (298:11,10 [7] TransitionsInTagHelperAttributes.cshtml) - Html - custom-
+ CSharpExpressionAttributeValue - (305:11,17 [9] TransitionsInTagHelperAttributes.cshtml) -
+ IntermediateToken - (307:11,19 [6] TransitionsInTagHelperAttributes.cshtml) - CSharp - @class
+ DefaultTagHelperProperty - (321:11,33 [15] TransitionsInTagHelperAttributes.cshtml) - age - int TestNamespace.PTagHelper.Age - HtmlAttributeValueStyle.DoubleQuotes
+ IntermediateToken - (321:11,33 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - 4
+ IntermediateToken - (322:11,34 [2] TransitionsInTagHelperAttributes.cshtml) - CSharp - *
+ IntermediateToken - (324:11,36 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp -
+ CSharpExpression - (325:11,37 [11] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (325:11,37 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - @
+ IntermediateToken - (326:11,38 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - (
+ IntermediateToken - (327:11,39 [8] TransitionsInTagHelperAttributes.cshtml) - CSharp - @int + 2
+ IntermediateToken - (335:11,47 [1] TransitionsInTagHelperAttributes.cshtml) - CSharp - )
+ DefaultTagHelperExecute -
+ HtmlContent - (342:11,54 [2] TransitionsInTagHelperAttributes.cshtml)
+ IntermediateToken - (342:11,54 [2] TransitionsInTagHelperAttributes.cshtml) - Html - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml
new file mode 100644
index 0000000000..bf1d796466
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml
@@ -0,0 +1,3 @@
+@{
+@DateTime.
+} \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.codegen.cs
new file mode 100644
index 0000000000..dab1c558b9
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.codegen.cs
@@ -0,0 +1,31 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UnfinishedExpressionInCode_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+
+
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml"
+__o = DateTime.;
+
+#line default
+#line hidden
+
+
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.ir.txt
new file mode 100644
index 0000000000..d74744737e
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.ir.txt
@@ -0,0 +1,17 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UnfinishedExpressionInCode_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [2] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (2:0,2 [2] UnfinishedExpressionInCode.cshtml) - CSharp - \n
+ CSharpExpression - (5:1,1 [9] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (5:1,1 [9] UnfinishedExpressionInCode.cshtml) - CSharp - DateTime.
+ CSharpCode - (14:1,10 [2] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (14:1,10 [2] UnfinishedExpressionInCode.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.mappings.txt
new file mode 100644
index 0000000000..df11ba8f84
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_DesignTime.mappings.txt
@@ -0,0 +1,19 @@
+Source Location: (2:0,2 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml)
+|
+|
+Generated Location: (663:17,14 [2] )
+|
+|
+
+Source Location: (5:1,1 [9] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml)
+|DateTime.|
+Generated Location: (775:20,6 [9] )
+|DateTime.|
+
+Source Location: (14:1,10 [2] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml)
+|
+|
+Generated Location: (840:24,22 [2] )
+|
+|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.codegen.cs
new file mode 100644
index 0000000000..f7141f4123
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.codegen.cs
@@ -0,0 +1,23 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "263a6264ce5a6790b4db8f6767ceefade6eaacba"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UnfinishedExpressionInCode_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"263a6264ce5a6790b4db8f6767ceefade6eaacba", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UnfinishedExpressionInCode_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode.cshtml"
+Write(DateTime.);
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.ir.txt
new file mode 100644
index 0000000000..a9958a1a62
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/UnfinishedExpressionInCode_Runtime.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_UnfinishedExpressionInCode_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ CSharpCode - (2:0,2 [2] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (2:0,2 [2] UnfinishedExpressionInCode.cshtml) - CSharp - \n
+ CSharpExpression - (5:1,1 [9] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (5:1,1 [9] UnfinishedExpressionInCode.cshtml) - CSharp - DateTime.
+ CSharpCode - (14:1,10 [2] UnfinishedExpressionInCode.cshtml)
+ IntermediateToken - (14:1,10 [2] UnfinishedExpressionInCode.cshtml) - CSharp - \n
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml
new file mode 100644
index 0000000000..90b2ae8222
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml
@@ -0,0 +1,10 @@
+@using System.IO
+@using Foo = System.Text.Encoding
+@using System
+
+@using static System
+@using static System.Console
+@using static global::System.Text.Encoding
+
+<p>Path's full type name is @typeof(Path).FullName</p>
+<p>Foo's actual full type name is @typeof(Foo).FullName</p> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.codegen.cs
new file mode 100644
index 0000000000..998ffa4d03
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.codegen.cs
@@ -0,0 +1,62 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using System.IO;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using Foo = System.Text.Encoding;
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using System;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static System;
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static System.Console;
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static global::System.Text.Encoding;
+
+#line default
+#line hidden
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Usings_DesignTime
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+ __o = typeof(Path).FullName;
+
+#line default
+#line hidden
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+ __o = typeof(Foo).FullName;
+
+#line default
+#line hidden
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.ir.txt
new file mode 100644
index 0000000000..958e9517f5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.ir.txt
@@ -0,0 +1,42 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ UsingDirective - (1:0,1 [15] Usings.cshtml) - System.IO
+ UsingDirective - (19:1,1 [32] Usings.cshtml) - Foo = System.Text.Encoding
+ UsingDirective - (54:2,1 [12] Usings.cshtml) - System
+ UsingDirective - (71:4,1 [19] Usings.cshtml) - static System
+ UsingDirective - (93:5,1 [27] Usings.cshtml) - static System.Console
+ UsingDirective - (123:6,1 [41] Usings.cshtml) - static global::System.Text.Encoding
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Usings_DesignTime - -
+ DesignTimeDirective -
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (16:0,16 [2] Usings.cshtml)
+ IntermediateToken - (16:0,16 [2] Usings.cshtml) - Html - \n
+ HtmlContent - (51:1,33 [2] Usings.cshtml)
+ IntermediateToken - (51:1,33 [2] Usings.cshtml) - Html - \n
+ HtmlContent - (66:2,13 [4] Usings.cshtml)
+ IntermediateToken - (66:2,13 [4] Usings.cshtml) - Html - \n\n
+ HtmlContent - (90:4,20 [2] Usings.cshtml)
+ IntermediateToken - (90:4,20 [2] Usings.cshtml) - Html - \n
+ HtmlContent - (120:5,28 [2] Usings.cshtml)
+ IntermediateToken - (120:5,28 [2] Usings.cshtml) - Html - \n
+ HtmlContent - (164:6,42 [32] Usings.cshtml)
+ IntermediateToken - (164:6,42 [4] Usings.cshtml) - Html - \n\n
+ IntermediateToken - (168:8,0 [3] Usings.cshtml) - Html - <p>
+ IntermediateToken - (171:8,3 [25] Usings.cshtml) - Html - Path's full type name is
+ CSharpExpression - (197:8,29 [21] Usings.cshtml)
+ IntermediateToken - (197:8,29 [21] Usings.cshtml) - CSharp - typeof(Path).FullName
+ HtmlContent - (218:8,50 [40] Usings.cshtml)
+ IntermediateToken - (218:8,50 [4] Usings.cshtml) - Html - </p>
+ IntermediateToken - (222:8,54 [2] Usings.cshtml) - Html - \n
+ IntermediateToken - (224:9,0 [3] Usings.cshtml) - Html - <p>
+ IntermediateToken - (227:9,3 [31] Usings.cshtml) - Html - Foo's actual full type name is
+ CSharpExpression - (259:9,35 [20] Usings.cshtml)
+ IntermediateToken - (259:9,35 [20] Usings.cshtml) - CSharp - typeof(Foo).FullName
+ HtmlContent - (279:9,55 [4] Usings.cshtml)
+ IntermediateToken - (279:9,55 [4] Usings.cshtml) - Html - </p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.mappings.txt
new file mode 100644
index 0000000000..3002ee4d8f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_DesignTime.mappings.txt
@@ -0,0 +1,40 @@
+Source Location: (1:0,1 [15] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using System.IO|
+Generated Location: (229:6,0 [15] )
+|using System.IO|
+
+Source Location: (19:1,1 [32] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using Foo = System.Text.Encoding|
+Generated Location: (360:11,0 [32] )
+|using Foo = System.Text.Encoding|
+
+Source Location: (54:2,1 [12] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using System|
+Generated Location: (508:16,0 [12] )
+|using System|
+
+Source Location: (71:4,1 [19] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using static System|
+Generated Location: (636:21,0 [19] )
+|using static System|
+
+Source Location: (93:5,1 [27] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using static System.Console|
+Generated Location: (771:26,0 [27] )
+|using static System.Console|
+
+Source Location: (123:6,1 [41] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|using static global::System.Text.Encoding|
+Generated Location: (914:31,0 [41] )
+|using static global::System.Text.Encoding|
+
+Source Location: (197:8,29 [21] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|typeof(Path).FullName|
+Generated Location: (1582:48,29 [21] )
+|typeof(Path).FullName|
+
+Source Location: (259:9,35 [20] TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml)
+|typeof(Foo).FullName|
+Generated Location: (1755:53,35 [20] )
+|typeof(Foo).FullName|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.codegen.cs
new file mode 100644
index 0000000000..e5260b1225
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.codegen.cs
@@ -0,0 +1,62 @@
+#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "6728cb5a1a2e5cec8b292fc113ea456ed9043ddc"
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles.TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Usings_Runtime), @"default", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml")]
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+#line 1 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using System.IO;
+
+#line default
+#line hidden
+#line 2 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using Foo = System.Text.Encoding;
+
+#line default
+#line hidden
+#line 3 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using System;
+
+#line default
+#line hidden
+#line 5 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static System;
+
+#line default
+#line hidden
+#line 6 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static System.Console;
+
+#line default
+#line hidden
+#line 7 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+using static global::System.Text.Encoding;
+
+#line default
+#line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"6728cb5a1a2e5cec8b292fc113ea456ed9043ddc", @"/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml")]
+ public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Usings_Runtime
+ {
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("\r\n");
+ WriteLiteral("\r\n<p>Path\'s full type name is ");
+#line 9 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+ Write(typeof(Path).FullName);
+
+#line default
+#line hidden
+ WriteLiteral("</p>\r\n<p>Foo\'s actual full type name is ");
+#line 10 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings.cshtml"
+ Write(typeof(Foo).FullName);
+
+#line default
+#line hidden
+ WriteLiteral("</p>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.ir.txt
new file mode 100644
index 0000000000..bdb82e73ec
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/Usings_Runtime.ir.txt
@@ -0,0 +1,29 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ UsingDirective - (1:0,1 [17] Usings.cshtml) - System.IO
+ UsingDirective - (19:1,1 [34] Usings.cshtml) - Foo = System.Text.Encoding
+ UsingDirective - (54:2,1 [14] Usings.cshtml) - System
+ UsingDirective - (71:4,1 [21] Usings.cshtml) - static System
+ UsingDirective - (93:5,1 [29] Usings.cshtml) - static System.Console
+ UsingDirective - (123:6,1 [43] Usings.cshtml) - static global::System.Text.Encoding
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_Usings_Runtime - -
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (68:3,0 [2] Usings.cshtml)
+ IntermediateToken - (68:3,0 [2] Usings.cshtml) - Html - \n
+ HtmlContent - (166:7,0 [30] Usings.cshtml)
+ IntermediateToken - (166:7,0 [2] Usings.cshtml) - Html - \n
+ IntermediateToken - (168:8,0 [3] Usings.cshtml) - Html - <p>
+ IntermediateToken - (171:8,3 [25] Usings.cshtml) - Html - Path's full type name is
+ CSharpExpression - (197:8,29 [21] Usings.cshtml)
+ IntermediateToken - (197:8,29 [21] Usings.cshtml) - CSharp - typeof(Path).FullName
+ HtmlContent - (218:8,50 [40] Usings.cshtml)
+ IntermediateToken - (218:8,50 [4] Usings.cshtml) - Html - </p>
+ IntermediateToken - (222:8,54 [2] Usings.cshtml) - Html - \n
+ IntermediateToken - (224:9,0 [3] Usings.cshtml) - Html - <p>
+ IntermediateToken - (227:9,3 [31] Usings.cshtml) - Html - Foo's actual full type name is
+ CSharpExpression - (259:9,35 [20] Usings.cshtml)
+ IntermediateToken - (259:9,35 [20] Usings.cshtml) - CSharp - typeof(Foo).FullName
+ HtmlContent - (279:9,55 [4] Usings.cshtml)
+ IntermediateToken - (279:9,55 [4] Usings.cshtml) - Html - </p>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.codegen.cs
new file mode 100644
index 0000000000..c50a6894ab
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.codegen.cs
@@ -0,0 +1,26 @@
+// <auto-generated/>
+#pragma warning disable 1591
+namespace Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+{
+ #line hidden
+ public class TestFiles_IntegrationTests_ExtensibleDirectiveTest_NamespaceToken
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = nameof(System.Globalization);
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ public async System.Threading.Tasks.Task ExecuteAsync()
+ {
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.cshtml
new file mode 100644
index 0000000000..0a8f147643
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.cshtml
@@ -0,0 +1 @@
+@custom System.Globalization \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.ir.txt
new file mode 100644
index 0000000000..ff111030c5
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.ir.txt
@@ -0,0 +1,12 @@
+Document -
+ NamespaceDeclaration - - Microsoft.AspNetCore.Razor.Language.IntegrationTests.TestFiles
+ ClassDeclaration - - public - TestFiles_IntegrationTests_ExtensibleDirectiveTest_NamespaceToken - -
+ DesignTimeDirective -
+ DirectiveToken - (8:0,8 [20] NamespaceToken.cshtml) - System.Globalization
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - public async - System.Threading.Tasks.Task - ExecuteAsync
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.mappings.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.mappings.txt
new file mode 100644
index 0000000000..c0b79c2c79
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.mappings.txt
@@ -0,0 +1,5 @@
+Source Location: (8:0,8 [20] TestFiles/IntegrationTests/ExtensibleDirectiveTest/NamespaceToken.cshtml)
+|System.Globalization|
+Generated Location: (410:10,44 [20] )
+|System.Globalization|
+
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.cshtml
new file mode 100644
index 0000000000..3a6c940b48
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.cshtml
@@ -0,0 +1,5 @@
+<html>
+<body>
+ <span val="@Hello" />
+</body>
+</html>" \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt
new file mode 100644
index 0000000000..e5c8ff35aa
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithConditionalAttribute.ir.txt
@@ -0,0 +1,22 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [25] HtmlWithConditionalAttribute.cshtml)
+ IntermediateToken - (0:0,0 [6] HtmlWithConditionalAttribute.cshtml) - Html - <html>
+ IntermediateToken - (6:0,6 [2] HtmlWithConditionalAttribute.cshtml) - Html - \n
+ IntermediateToken - (8:1,0 [6] HtmlWithConditionalAttribute.cshtml) - Html - <body>
+ IntermediateToken - (14:1,6 [6] HtmlWithConditionalAttribute.cshtml) - Html - \n
+ IntermediateToken - (20:2,4 [5] HtmlWithConditionalAttribute.cshtml) - Html - <span
+ HtmlAttribute - (25:2,9 [13] HtmlWithConditionalAttribute.cshtml) - val=" - "
+ CSharpExpressionAttributeValue - (31:2,15 [6] HtmlWithConditionalAttribute.cshtml) -
+ IntermediateToken - (32:2,16 [5] HtmlWithConditionalAttribute.cshtml) - CSharp - Hello
+ HtmlContent - (38:2,22 [22] HtmlWithConditionalAttribute.cshtml)
+ IntermediateToken - (38:2,22 [3] HtmlWithConditionalAttribute.cshtml) - Html - />
+ IntermediateToken - (41:2,25 [2] HtmlWithConditionalAttribute.cshtml) - Html - \n
+ IntermediateToken - (43:3,0 [7] HtmlWithConditionalAttribute.cshtml) - Html - </body>
+ IntermediateToken - (50:3,7 [2] HtmlWithConditionalAttribute.cshtml) - Html - \n
+ IntermediateToken - (52:4,0 [7] HtmlWithConditionalAttribute.cshtml) - Html - </html>
+ IntermediateToken - (59:4,7 [1] HtmlWithConditionalAttribute.cshtml) - Html - "
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.cshtml
new file mode 100644
index 0000000000..ac18b96408
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.cshtml
@@ -0,0 +1,5 @@
+<html>
+<body>
+ <span data-val="@Hello" />
+</body>
+</html>" \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt
new file mode 100644
index 0000000000..3486809b58
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/HtmlAttributeIntegrationTest/HtmlWithDataDashAttribute.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (0:0,0 [36] HtmlWithDataDashAttribute.cshtml)
+ IntermediateToken - (0:0,0 [6] HtmlWithDataDashAttribute.cshtml) - Html - <html>
+ IntermediateToken - (6:0,6 [2] HtmlWithDataDashAttribute.cshtml) - Html - \n
+ IntermediateToken - (8:1,0 [6] HtmlWithDataDashAttribute.cshtml) - Html - <body>
+ IntermediateToken - (14:1,6 [6] HtmlWithDataDashAttribute.cshtml) - Html - \n
+ IntermediateToken - (20:2,4 [5] HtmlWithDataDashAttribute.cshtml) - Html - <span
+ IntermediateToken - (25:2,9 [11] HtmlWithDataDashAttribute.cshtml) - Html - data-val="
+ CSharpExpression - (37:2,21 [5] HtmlWithDataDashAttribute.cshtml)
+ IntermediateToken - (37:2,21 [5] HtmlWithDataDashAttribute.cshtml) - CSharp - Hello
+ HtmlContent - (42:2,26 [23] HtmlWithDataDashAttribute.cshtml)
+ IntermediateToken - (42:2,26 [1] HtmlWithDataDashAttribute.cshtml) - Html - "
+ IntermediateToken - (43:2,27 [3] HtmlWithDataDashAttribute.cshtml) - Html - />
+ IntermediateToken - (46:2,30 [2] HtmlWithDataDashAttribute.cshtml) - Html - \n
+ IntermediateToken - (48:3,0 [7] HtmlWithDataDashAttribute.cshtml) - Html - </body>
+ IntermediateToken - (55:3,7 [2] HtmlWithDataDashAttribute.cshtml) - Html - \n
+ IntermediateToken - (57:4,0 [7] HtmlWithDataDashAttribute.cshtml) - Html - </html>
+ IntermediateToken - (64:4,7 [1] HtmlWithDataDashAttribute.cshtml) - Html - "
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs
new file mode 100644
index 0000000000..38d08a7c75
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.codegen.cs
@@ -0,0 +1,18 @@
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Razor.Template), @"default", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml")]
+namespace Razor
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"38aa8e26c5d2a85c61d8e93fe69dd326fe82671b", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml")]
+ public class Template : MyBaseType
+ {
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<h1>Hello world!</h1>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml
new file mode 100644
index 0000000000..6df88a66a1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithBaseType.cshtml
@@ -0,0 +1 @@
+<h1>Hello world!</h1> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs
new file mode 100644
index 0000000000..9c5c3a8a73
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.codegen.cs
@@ -0,0 +1,18 @@
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Razor.MyClass), @"default", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml")]
+namespace Razor
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"38aa8e26c5d2a85c61d8e93fe69dd326fe82671b", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml")]
+ protected internal class MyClass<TValue> : CustomBaseType, global::System.IDisposable
+ {
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<h1>Hello world!</h1>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml
new file mode 100644
index 0000000000..6df88a66a1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithConfigureClass.cshtml
@@ -0,0 +1 @@
+<h1>Hello world!</h1> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs
new file mode 100644
index 0000000000..0ca4f5d061
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.codegen.cs
@@ -0,0 +1,18 @@
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(Razor.Template), @"default", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml")]
+namespace Razor
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"38aa8e26c5d2a85c61d8e93fe69dd326fe82671b", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml")]
+ public class Template
+ {
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<h1>Hello world!</h1>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml
new file mode 100644
index 0000000000..6df88a66a1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithDefaults.cshtml
@@ -0,0 +1 @@
+<h1>Hello world!</h1> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs
new file mode 100644
index 0000000000..8cff2ae67f
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.codegen.cs
@@ -0,0 +1,18 @@
+// <auto-generated/>
+#pragma warning disable 1591
+[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(MyApp.Razor.Views.Template), @"default", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml")]
+namespace MyApp.Razor.Views
+{
+ #line hidden
+ [global::Microsoft.AspNetCore.Razor.Hosting.RazorSourceChecksumAttribute(@"SHA1", @"38aa8e26c5d2a85c61d8e93fe69dd326fe82671b", @"/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml")]
+ public class Template
+ {
+ #pragma warning disable 1998
+ public async override global::System.Threading.Tasks.Task ExecuteAsync()
+ {
+ WriteLiteral("<h1>Hello world!</h1>");
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml
new file mode 100644
index 0000000000..6df88a66a1
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/RazorTemplateEngineIntegrationTest/GenerateCodeWithSetNamespace.cshtml
@@ -0,0 +1 @@
+<h1>Hello world!</h1> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.cshtml
new file mode 100644
index 0000000000..e8c8937563
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.cshtml
@@ -0,0 +1,5 @@
+@addTagHelper *, TestAssembly
+<p someattr>Hola</p>
+<form unbound="foo">
+ <input value=Hello type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt
new file mode 100644
index 0000000000..ab0e72e99a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/NestedTagHelpers.ir.txt
@@ -0,0 +1,37 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ PreallocatedTagHelperPropertyValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.DoubleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_2 - unbound - foo - HtmlAttributeValueStyle.DoubleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::PTagHelper - __PTagHelper
+ FieldDeclaration - - private - global::FormTagHelper - __FormTagHelper
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ TagHelper - (31:1,0 [20] NestedTagHelpers.cshtml) - p - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (43:1,12 [4] NestedTagHelpers.cshtml)
+ IntermediateToken - (43:1,12 [4] NestedTagHelpers.cshtml) - Html - Hola
+ DefaultTagHelperCreate - - PTagHelper
+ DefaultTagHelperHtmlAttribute - - someattr - HtmlAttributeValueStyle.Minimized
+ DefaultTagHelperExecute -
+ HtmlContent - (51:1,20 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (51:1,20 [2] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (53:2,0 [68] NestedTagHelpers.cshtml) - form - TagMode.StartTagAndEndTag
+ DefaultTagHelperBody -
+ HtmlContent - (73:2,20 [6] NestedTagHelpers.cshtml)
+ IntermediateToken - (73:2,20 [6] NestedTagHelpers.cshtml) - Html - \n
+ TagHelper - (79:3,4 [33] NestedTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ PreallocatedTagHelperProperty - (92:3,17 [5] NestedTagHelpers.cshtml) - __tagHelperAttribute_0 - value - FooProp
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (112:3,37 [2] NestedTagHelpers.cshtml)
+ IntermediateToken - (112:3,37 [2] NestedTagHelpers.cshtml) - Html - \n
+ DefaultTagHelperCreate - - FormTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_2
+ DefaultTagHelperExecute -
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.cshtml
new file mode 100644
index 0000000000..bd4ce8107a
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.cshtml
@@ -0,0 +1,5 @@
+@addTagHelper *, TestAssembly
+<p>Hola</p>
+<form>
+ <input value='Hello' type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt
new file mode 100644
index 0000000000..80661692b6
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/SimpleTagHelpers.ir.txt
@@ -0,0 +1,26 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - value - Hello - HtmlAttributeValueStyle.SingleQuotes
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_1 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [25] SimpleTagHelpers.cshtml)
+ IntermediateToken - (31:1,0 [3] SimpleTagHelpers.cshtml) - Html - <p>
+ IntermediateToken - (34:1,3 [4] SimpleTagHelpers.cshtml) - Html - Hola
+ IntermediateToken - (38:1,7 [4] SimpleTagHelpers.cshtml) - Html - </p>
+ IntermediateToken - (42:1,11 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (44:2,0 [6] SimpleTagHelpers.cshtml) - Html - <form>
+ IntermediateToken - (50:2,6 [6] SimpleTagHelpers.cshtml) - Html - \n
+ TagHelper - (56:3,4 [35] SimpleTagHelpers.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_1
+ DefaultTagHelperExecute -
+ HtmlContent - (91:3,39 [9] SimpleTagHelpers.cshtml)
+ IntermediateToken - (91:3,39 [2] SimpleTagHelpers.cshtml) - Html - \n
+ IntermediateToken - (93:4,0 [7] SimpleTagHelpers.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.cshtml
new file mode 100644
index 0000000000..83023559d3
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.cshtml
@@ -0,0 +1,4 @@
+@addTagHelper *, TestAssembly
+<form>
+ <input bound=@Hello type='text' />
+</form> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt
new file mode 100644
index 0000000000..3a72431dd8
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/IntegrationTests/TagHelpersIntegrationTest/TagHelpersWithBoundAttributes.ir.txt
@@ -0,0 +1,23 @@
+Document -
+ RazorCompiledItemAttribute -
+ NamespaceDeclaration - - Razor
+ RazorSourceChecksumAttribute -
+ ClassDeclaration - - public - Template - -
+ PreallocatedTagHelperHtmlAttributeValue - - __tagHelperAttribute_0 - type - text - HtmlAttributeValueStyle.SingleQuotes
+ DefaultTagHelperRuntime -
+ FieldDeclaration - - private - global::InputTagHelper - __InputTagHelper
+ MethodDeclaration - - public async override - global::System.Threading.Tasks.Task - ExecuteAsync
+ HtmlContent - (31:1,0 [12] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (31:1,0 [6] TagHelpersWithBoundAttributes.cshtml) - Html - <form>
+ IntermediateToken - (37:1,6 [6] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ TagHelper - (43:2,4 [34] TagHelpersWithBoundAttributes.cshtml) - input - TagMode.SelfClosing
+ DefaultTagHelperBody -
+ DefaultTagHelperCreate - - InputTagHelper
+ DefaultTagHelperProperty - (56:2,17 [6] TagHelpersWithBoundAttributes.cshtml) - bound - string InputTagHelper.FooProp - HtmlAttributeValueStyle.DoubleQuotes
+ CSharpExpression - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (57:2,18 [5] TagHelpersWithBoundAttributes.cshtml) - CSharp - Hello
+ PreallocatedTagHelperHtmlAttribute - - __tagHelperAttribute_0
+ DefaultTagHelperExecute -
+ HtmlContent - (77:2,38 [9] TagHelpersWithBoundAttributes.cshtml)
+ IntermediateToken - (77:2,38 [2] TagHelpersWithBoundAttributes.cshtml) - Html - \n
+ IntermediateToken - (79:3,0 [7] TagHelpersWithBoundAttributes.cshtml) - Html - </form>
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/Source/BasicMarkup.cshtml b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/Source/BasicMarkup.cshtml
new file mode 100644
index 0000000000..384a7a6deb
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/Source/BasicMarkup.cshtml
@@ -0,0 +1,8 @@
+<html>
+<head>
+ <title>This is the title.</title>
+</head>
+<body>
+ <a href="http://contoso.com">Link to Contoso.</a>
+</body>
+</html> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/nested-1000.html b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/nested-1000.html
new file mode 100644
index 0000000000..3c35bdbcbe
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestFiles/nested-1000.html
@@ -0,0 +1,2002 @@
+<outer>
+<elem-1>
+<elem-2>
+<elem-3>
+<elem-4>
+<elem-5>
+<elem-6>
+<elem-7>
+<elem-8>
+<elem-9>
+<elem-10>
+<elem-11>
+<elem-12>
+<elem-13>
+<elem-14>
+<elem-15>
+<elem-16>
+<elem-17>
+<elem-18>
+<elem-19>
+<elem-20>
+<elem-21>
+<elem-22>
+<elem-23>
+<elem-24>
+<elem-25>
+<elem-26>
+<elem-27>
+<elem-28>
+<elem-29>
+<elem-30>
+<elem-31>
+<elem-32>
+<elem-33>
+<elem-34>
+<elem-35>
+<elem-36>
+<elem-37>
+<elem-38>
+<elem-39>
+<elem-40>
+<elem-41>
+<elem-42>
+<elem-43>
+<elem-44>
+<elem-45>
+<elem-46>
+<elem-47>
+<elem-48>
+<elem-49>
+<elem-50>
+<elem-51>
+<elem-52>
+<elem-53>
+<elem-54>
+<elem-55>
+<elem-56>
+<elem-57>
+<elem-58>
+<elem-59>
+<elem-60>
+<elem-61>
+<elem-62>
+<elem-63>
+<elem-64>
+<elem-65>
+<elem-66>
+<elem-67>
+<elem-68>
+<elem-69>
+<elem-70>
+<elem-71>
+<elem-72>
+<elem-73>
+<elem-74>
+<elem-75>
+<elem-76>
+<elem-77>
+<elem-78>
+<elem-79>
+<elem-80>
+<elem-81>
+<elem-82>
+<elem-83>
+<elem-84>
+<elem-85>
+<elem-86>
+<elem-87>
+<elem-88>
+<elem-89>
+<elem-90>
+<elem-91>
+<elem-92>
+<elem-93>
+<elem-94>
+<elem-95>
+<elem-96>
+<elem-97>
+<elem-98>
+<elem-99>
+<elem-100>
+<elem-101>
+<elem-102>
+<elem-103>
+<elem-104>
+<elem-105>
+<elem-106>
+<elem-107>
+<elem-108>
+<elem-109>
+<elem-110>
+<elem-111>
+<elem-112>
+<elem-113>
+<elem-114>
+<elem-115>
+<elem-116>
+<elem-117>
+<elem-118>
+<elem-119>
+<elem-120>
+<elem-121>
+<elem-122>
+<elem-123>
+<elem-124>
+<elem-125>
+<elem-126>
+<elem-127>
+<elem-128>
+<elem-129>
+<elem-130>
+<elem-131>
+<elem-132>
+<elem-133>
+<elem-134>
+<elem-135>
+<elem-136>
+<elem-137>
+<elem-138>
+<elem-139>
+<elem-140>
+<elem-141>
+<elem-142>
+<elem-143>
+<elem-144>
+<elem-145>
+<elem-146>
+<elem-147>
+<elem-148>
+<elem-149>
+<elem-150>
+<elem-151>
+<elem-152>
+<elem-153>
+<elem-154>
+<elem-155>
+<elem-156>
+<elem-157>
+<elem-158>
+<elem-159>
+<elem-160>
+<elem-161>
+<elem-162>
+<elem-163>
+<elem-164>
+<elem-165>
+<elem-166>
+<elem-167>
+<elem-168>
+<elem-169>
+<elem-170>
+<elem-171>
+<elem-172>
+<elem-173>
+<elem-174>
+<elem-175>
+<elem-176>
+<elem-177>
+<elem-178>
+<elem-179>
+<elem-180>
+<elem-181>
+<elem-182>
+<elem-183>
+<elem-184>
+<elem-185>
+<elem-186>
+<elem-187>
+<elem-188>
+<elem-189>
+<elem-190>
+<elem-191>
+<elem-192>
+<elem-193>
+<elem-194>
+<elem-195>
+<elem-196>
+<elem-197>
+<elem-198>
+<elem-199>
+<elem-200>
+<elem-201>
+<elem-202>
+<elem-203>
+<elem-204>
+<elem-205>
+<elem-206>
+<elem-207>
+<elem-208>
+<elem-209>
+<elem-210>
+<elem-211>
+<elem-212>
+<elem-213>
+<elem-214>
+<elem-215>
+<elem-216>
+<elem-217>
+<elem-218>
+<elem-219>
+<elem-220>
+<elem-221>
+<elem-222>
+<elem-223>
+<elem-224>
+<elem-225>
+<elem-226>
+<elem-227>
+<elem-228>
+<elem-229>
+<elem-230>
+<elem-231>
+<elem-232>
+<elem-233>
+<elem-234>
+<elem-235>
+<elem-236>
+<elem-237>
+<elem-238>
+<elem-239>
+<elem-240>
+<elem-241>
+<elem-242>
+<elem-243>
+<elem-244>
+<elem-245>
+<elem-246>
+<elem-247>
+<elem-248>
+<elem-249>
+<elem-250>
+<elem-251>
+<elem-252>
+<elem-253>
+<elem-254>
+<elem-255>
+<elem-256>
+<elem-257>
+<elem-258>
+<elem-259>
+<elem-260>
+<elem-261>
+<elem-262>
+<elem-263>
+<elem-264>
+<elem-265>
+<elem-266>
+<elem-267>
+<elem-268>
+<elem-269>
+<elem-270>
+<elem-271>
+<elem-272>
+<elem-273>
+<elem-274>
+<elem-275>
+<elem-276>
+<elem-277>
+<elem-278>
+<elem-279>
+<elem-280>
+<elem-281>
+<elem-282>
+<elem-283>
+<elem-284>
+<elem-285>
+<elem-286>
+<elem-287>
+<elem-288>
+<elem-289>
+<elem-290>
+<elem-291>
+<elem-292>
+<elem-293>
+<elem-294>
+<elem-295>
+<elem-296>
+<elem-297>
+<elem-298>
+<elem-299>
+<elem-300>
+<elem-301>
+<elem-302>
+<elem-303>
+<elem-304>
+<elem-305>
+<elem-306>
+<elem-307>
+<elem-308>
+<elem-309>
+<elem-310>
+<elem-311>
+<elem-312>
+<elem-313>
+<elem-314>
+<elem-315>
+<elem-316>
+<elem-317>
+<elem-318>
+<elem-319>
+<elem-320>
+<elem-321>
+<elem-322>
+<elem-323>
+<elem-324>
+<elem-325>
+<elem-326>
+<elem-327>
+<elem-328>
+<elem-329>
+<elem-330>
+<elem-331>
+<elem-332>
+<elem-333>
+<elem-334>
+<elem-335>
+<elem-336>
+<elem-337>
+<elem-338>
+<elem-339>
+<elem-340>
+<elem-341>
+<elem-342>
+<elem-343>
+<elem-344>
+<elem-345>
+<elem-346>
+<elem-347>
+<elem-348>
+<elem-349>
+<elem-350>
+<elem-351>
+<elem-352>
+<elem-353>
+<elem-354>
+<elem-355>
+<elem-356>
+<elem-357>
+<elem-358>
+<elem-359>
+<elem-360>
+<elem-361>
+<elem-362>
+<elem-363>
+<elem-364>
+<elem-365>
+<elem-366>
+<elem-367>
+<elem-368>
+<elem-369>
+<elem-370>
+<elem-371>
+<elem-372>
+<elem-373>
+<elem-374>
+<elem-375>
+<elem-376>
+<elem-377>
+<elem-378>
+<elem-379>
+<elem-380>
+<elem-381>
+<elem-382>
+<elem-383>
+<elem-384>
+<elem-385>
+<elem-386>
+<elem-387>
+<elem-388>
+<elem-389>
+<elem-390>
+<elem-391>
+<elem-392>
+<elem-393>
+<elem-394>
+<elem-395>
+<elem-396>
+<elem-397>
+<elem-398>
+<elem-399>
+<elem-400>
+<elem-401>
+<elem-402>
+<elem-403>
+<elem-404>
+<elem-405>
+<elem-406>
+<elem-407>
+<elem-408>
+<elem-409>
+<elem-410>
+<elem-411>
+<elem-412>
+<elem-413>
+<elem-414>
+<elem-415>
+<elem-416>
+<elem-417>
+<elem-418>
+<elem-419>
+<elem-420>
+<elem-421>
+<elem-422>
+<elem-423>
+<elem-424>
+<elem-425>
+<elem-426>
+<elem-427>
+<elem-428>
+<elem-429>
+<elem-430>
+<elem-431>
+<elem-432>
+<elem-433>
+<elem-434>
+<elem-435>
+<elem-436>
+<elem-437>
+<elem-438>
+<elem-439>
+<elem-440>
+<elem-441>
+<elem-442>
+<elem-443>
+<elem-444>
+<elem-445>
+<elem-446>
+<elem-447>
+<elem-448>
+<elem-449>
+<elem-450>
+<elem-451>
+<elem-452>
+<elem-453>
+<elem-454>
+<elem-455>
+<elem-456>
+<elem-457>
+<elem-458>
+<elem-459>
+<elem-460>
+<elem-461>
+<elem-462>
+<elem-463>
+<elem-464>
+<elem-465>
+<elem-466>
+<elem-467>
+<elem-468>
+<elem-469>
+<elem-470>
+<elem-471>
+<elem-472>
+<elem-473>
+<elem-474>
+<elem-475>
+<elem-476>
+<elem-477>
+<elem-478>
+<elem-479>
+<elem-480>
+<elem-481>
+<elem-482>
+<elem-483>
+<elem-484>
+<elem-485>
+<elem-486>
+<elem-487>
+<elem-488>
+<elem-489>
+<elem-490>
+<elem-491>
+<elem-492>
+<elem-493>
+<elem-494>
+<elem-495>
+<elem-496>
+<elem-497>
+<elem-498>
+<elem-499>
+<elem-500>
+<elem-501>
+<elem-502>
+<elem-503>
+<elem-504>
+<elem-505>
+<elem-506>
+<elem-507>
+<elem-508>
+<elem-509>
+<elem-510>
+<elem-511>
+<elem-512>
+<elem-513>
+<elem-514>
+<elem-515>
+<elem-516>
+<elem-517>
+<elem-518>
+<elem-519>
+<elem-520>
+<elem-521>
+<elem-522>
+<elem-523>
+<elem-524>
+<elem-525>
+<elem-526>
+<elem-527>
+<elem-528>
+<elem-529>
+<elem-530>
+<elem-531>
+<elem-532>
+<elem-533>
+<elem-534>
+<elem-535>
+<elem-536>
+<elem-537>
+<elem-538>
+<elem-539>
+<elem-540>
+<elem-541>
+<elem-542>
+<elem-543>
+<elem-544>
+<elem-545>
+<elem-546>
+<elem-547>
+<elem-548>
+<elem-549>
+<elem-550>
+<elem-551>
+<elem-552>
+<elem-553>
+<elem-554>
+<elem-555>
+<elem-556>
+<elem-557>
+<elem-558>
+<elem-559>
+<elem-560>
+<elem-561>
+<elem-562>
+<elem-563>
+<elem-564>
+<elem-565>
+<elem-566>
+<elem-567>
+<elem-568>
+<elem-569>
+<elem-570>
+<elem-571>
+<elem-572>
+<elem-573>
+<elem-574>
+<elem-575>
+<elem-576>
+<elem-577>
+<elem-578>
+<elem-579>
+<elem-580>
+<elem-581>
+<elem-582>
+<elem-583>
+<elem-584>
+<elem-585>
+<elem-586>
+<elem-587>
+<elem-588>
+<elem-589>
+<elem-590>
+<elem-591>
+<elem-592>
+<elem-593>
+<elem-594>
+<elem-595>
+<elem-596>
+<elem-597>
+<elem-598>
+<elem-599>
+<elem-600>
+<elem-601>
+<elem-602>
+<elem-603>
+<elem-604>
+<elem-605>
+<elem-606>
+<elem-607>
+<elem-608>
+<elem-609>
+<elem-610>
+<elem-611>
+<elem-612>
+<elem-613>
+<elem-614>
+<elem-615>
+<elem-616>
+<elem-617>
+<elem-618>
+<elem-619>
+<elem-620>
+<elem-621>
+<elem-622>
+<elem-623>
+<elem-624>
+<elem-625>
+<elem-626>
+<elem-627>
+<elem-628>
+<elem-629>
+<elem-630>
+<elem-631>
+<elem-632>
+<elem-633>
+<elem-634>
+<elem-635>
+<elem-636>
+<elem-637>
+<elem-638>
+<elem-639>
+<elem-640>
+<elem-641>
+<elem-642>
+<elem-643>
+<elem-644>
+<elem-645>
+<elem-646>
+<elem-647>
+<elem-648>
+<elem-649>
+<elem-650>
+<elem-651>
+<elem-652>
+<elem-653>
+<elem-654>
+<elem-655>
+<elem-656>
+<elem-657>
+<elem-658>
+<elem-659>
+<elem-660>
+<elem-661>
+<elem-662>
+<elem-663>
+<elem-664>
+<elem-665>
+<elem-666>
+<elem-667>
+<elem-668>
+<elem-669>
+<elem-670>
+<elem-671>
+<elem-672>
+<elem-673>
+<elem-674>
+<elem-675>
+<elem-676>
+<elem-677>
+<elem-678>
+<elem-679>
+<elem-680>
+<elem-681>
+<elem-682>
+<elem-683>
+<elem-684>
+<elem-685>
+<elem-686>
+<elem-687>
+<elem-688>
+<elem-689>
+<elem-690>
+<elem-691>
+<elem-692>
+<elem-693>
+<elem-694>
+<elem-695>
+<elem-696>
+<elem-697>
+<elem-698>
+<elem-699>
+<elem-700>
+<elem-701>
+<elem-702>
+<elem-703>
+<elem-704>
+<elem-705>
+<elem-706>
+<elem-707>
+<elem-708>
+<elem-709>
+<elem-710>
+<elem-711>
+<elem-712>
+<elem-713>
+<elem-714>
+<elem-715>
+<elem-716>
+<elem-717>
+<elem-718>
+<elem-719>
+<elem-720>
+<elem-721>
+<elem-722>
+<elem-723>
+<elem-724>
+<elem-725>
+<elem-726>
+<elem-727>
+<elem-728>
+<elem-729>
+<elem-730>
+<elem-731>
+<elem-732>
+<elem-733>
+<elem-734>
+<elem-735>
+<elem-736>
+<elem-737>
+<elem-738>
+<elem-739>
+<elem-740>
+<elem-741>
+<elem-742>
+<elem-743>
+<elem-744>
+<elem-745>
+<elem-746>
+<elem-747>
+<elem-748>
+<elem-749>
+<elem-750>
+<elem-751>
+<elem-752>
+<elem-753>
+<elem-754>
+<elem-755>
+<elem-756>
+<elem-757>
+<elem-758>
+<elem-759>
+<elem-760>
+<elem-761>
+<elem-762>
+<elem-763>
+<elem-764>
+<elem-765>
+<elem-766>
+<elem-767>
+<elem-768>
+<elem-769>
+<elem-770>
+<elem-771>
+<elem-772>
+<elem-773>
+<elem-774>
+<elem-775>
+<elem-776>
+<elem-777>
+<elem-778>
+<elem-779>
+<elem-780>
+<elem-781>
+<elem-782>
+<elem-783>
+<elem-784>
+<elem-785>
+<elem-786>
+<elem-787>
+<elem-788>
+<elem-789>
+<elem-790>
+<elem-791>
+<elem-792>
+<elem-793>
+<elem-794>
+<elem-795>
+<elem-796>
+<elem-797>
+<elem-798>
+<elem-799>
+<elem-800>
+<elem-801>
+<elem-802>
+<elem-803>
+<elem-804>
+<elem-805>
+<elem-806>
+<elem-807>
+<elem-808>
+<elem-809>
+<elem-810>
+<elem-811>
+<elem-812>
+<elem-813>
+<elem-814>
+<elem-815>
+<elem-816>
+<elem-817>
+<elem-818>
+<elem-819>
+<elem-820>
+<elem-821>
+<elem-822>
+<elem-823>
+<elem-824>
+<elem-825>
+<elem-826>
+<elem-827>
+<elem-828>
+<elem-829>
+<elem-830>
+<elem-831>
+<elem-832>
+<elem-833>
+<elem-834>
+<elem-835>
+<elem-836>
+<elem-837>
+<elem-838>
+<elem-839>
+<elem-840>
+<elem-841>
+<elem-842>
+<elem-843>
+<elem-844>
+<elem-845>
+<elem-846>
+<elem-847>
+<elem-848>
+<elem-849>
+<elem-850>
+<elem-851>
+<elem-852>
+<elem-853>
+<elem-854>
+<elem-855>
+<elem-856>
+<elem-857>
+<elem-858>
+<elem-859>
+<elem-860>
+<elem-861>
+<elem-862>
+<elem-863>
+<elem-864>
+<elem-865>
+<elem-866>
+<elem-867>
+<elem-868>
+<elem-869>
+<elem-870>
+<elem-871>
+<elem-872>
+<elem-873>
+<elem-874>
+<elem-875>
+<elem-876>
+<elem-877>
+<elem-878>
+<elem-879>
+<elem-880>
+<elem-881>
+<elem-882>
+<elem-883>
+<elem-884>
+<elem-885>
+<elem-886>
+<elem-887>
+<elem-888>
+<elem-889>
+<elem-890>
+<elem-891>
+<elem-892>
+<elem-893>
+<elem-894>
+<elem-895>
+<elem-896>
+<elem-897>
+<elem-898>
+<elem-899>
+<elem-900>
+<elem-901>
+<elem-902>
+<elem-903>
+<elem-904>
+<elem-905>
+<elem-906>
+<elem-907>
+<elem-908>
+<elem-909>
+<elem-910>
+<elem-911>
+<elem-912>
+<elem-913>
+<elem-914>
+<elem-915>
+<elem-916>
+<elem-917>
+<elem-918>
+<elem-919>
+<elem-920>
+<elem-921>
+<elem-922>
+<elem-923>
+<elem-924>
+<elem-925>
+<elem-926>
+<elem-927>
+<elem-928>
+<elem-929>
+<elem-930>
+<elem-931>
+<elem-932>
+<elem-933>
+<elem-934>
+<elem-935>
+<elem-936>
+<elem-937>
+<elem-938>
+<elem-939>
+<elem-940>
+<elem-941>
+<elem-942>
+<elem-943>
+<elem-944>
+<elem-945>
+<elem-946>
+<elem-947>
+<elem-948>
+<elem-949>
+<elem-950>
+<elem-951>
+<elem-952>
+<elem-953>
+<elem-954>
+<elem-955>
+<elem-956>
+<elem-957>
+<elem-958>
+<elem-959>
+<elem-960>
+<elem-961>
+<elem-962>
+<elem-963>
+<elem-964>
+<elem-965>
+<elem-966>
+<elem-967>
+<elem-968>
+<elem-969>
+<elem-970>
+<elem-971>
+<elem-972>
+<elem-973>
+<elem-974>
+<elem-975>
+<elem-976>
+<elem-977>
+<elem-978>
+<elem-979>
+<elem-980>
+<elem-981>
+<elem-982>
+<elem-983>
+<elem-984>
+<elem-985>
+<elem-986>
+<elem-987>
+<elem-988>
+<elem-989>
+<elem-990>
+<elem-991>
+<elem-992>
+<elem-993>
+<elem-994>
+<elem-995>
+<elem-996>
+<elem-997>
+<elem-998>
+<elem-999>
+<elem-1000>
+</elem-1000>
+</elem-999>
+</elem-998>
+</elem-997>
+</elem-996>
+</elem-995>
+</elem-994>
+</elem-993>
+</elem-992>
+</elem-991>
+</elem-990>
+</elem-989>
+</elem-988>
+</elem-987>
+</elem-986>
+</elem-985>
+</elem-984>
+</elem-983>
+</elem-982>
+</elem-981>
+</elem-980>
+</elem-979>
+</elem-978>
+</elem-977>
+</elem-976>
+</elem-975>
+</elem-974>
+</elem-973>
+</elem-972>
+</elem-971>
+</elem-970>
+</elem-969>
+</elem-968>
+</elem-967>
+</elem-966>
+</elem-965>
+</elem-964>
+</elem-963>
+</elem-962>
+</elem-961>
+</elem-960>
+</elem-959>
+</elem-958>
+</elem-957>
+</elem-956>
+</elem-955>
+</elem-954>
+</elem-953>
+</elem-952>
+</elem-951>
+</elem-950>
+</elem-949>
+</elem-948>
+</elem-947>
+</elem-946>
+</elem-945>
+</elem-944>
+</elem-943>
+</elem-942>
+</elem-941>
+</elem-940>
+</elem-939>
+</elem-938>
+</elem-937>
+</elem-936>
+</elem-935>
+</elem-934>
+</elem-933>
+</elem-932>
+</elem-931>
+</elem-930>
+</elem-929>
+</elem-928>
+</elem-927>
+</elem-926>
+</elem-925>
+</elem-924>
+</elem-923>
+</elem-922>
+</elem-921>
+</elem-920>
+</elem-919>
+</elem-918>
+</elem-917>
+</elem-916>
+</elem-915>
+</elem-914>
+</elem-913>
+</elem-912>
+</elem-911>
+</elem-910>
+</elem-909>
+</elem-908>
+</elem-907>
+</elem-906>
+</elem-905>
+</elem-904>
+</elem-903>
+</elem-902>
+</elem-901>
+</elem-900>
+</elem-899>
+</elem-898>
+</elem-897>
+</elem-896>
+</elem-895>
+</elem-894>
+</elem-893>
+</elem-892>
+</elem-891>
+</elem-890>
+</elem-889>
+</elem-888>
+</elem-887>
+</elem-886>
+</elem-885>
+</elem-884>
+</elem-883>
+</elem-882>
+</elem-881>
+</elem-880>
+</elem-879>
+</elem-878>
+</elem-877>
+</elem-876>
+</elem-875>
+</elem-874>
+</elem-873>
+</elem-872>
+</elem-871>
+</elem-870>
+</elem-869>
+</elem-868>
+</elem-867>
+</elem-866>
+</elem-865>
+</elem-864>
+</elem-863>
+</elem-862>
+</elem-861>
+</elem-860>
+</elem-859>
+</elem-858>
+</elem-857>
+</elem-856>
+</elem-855>
+</elem-854>
+</elem-853>
+</elem-852>
+</elem-851>
+</elem-850>
+</elem-849>
+</elem-848>
+</elem-847>
+</elem-846>
+</elem-845>
+</elem-844>
+</elem-843>
+</elem-842>
+</elem-841>
+</elem-840>
+</elem-839>
+</elem-838>
+</elem-837>
+</elem-836>
+</elem-835>
+</elem-834>
+</elem-833>
+</elem-832>
+</elem-831>
+</elem-830>
+</elem-829>
+</elem-828>
+</elem-827>
+</elem-826>
+</elem-825>
+</elem-824>
+</elem-823>
+</elem-822>
+</elem-821>
+</elem-820>
+</elem-819>
+</elem-818>
+</elem-817>
+</elem-816>
+</elem-815>
+</elem-814>
+</elem-813>
+</elem-812>
+</elem-811>
+</elem-810>
+</elem-809>
+</elem-808>
+</elem-807>
+</elem-806>
+</elem-805>
+</elem-804>
+</elem-803>
+</elem-802>
+</elem-801>
+</elem-800>
+</elem-799>
+</elem-798>
+</elem-797>
+</elem-796>
+</elem-795>
+</elem-794>
+</elem-793>
+</elem-792>
+</elem-791>
+</elem-790>
+</elem-789>
+</elem-788>
+</elem-787>
+</elem-786>
+</elem-785>
+</elem-784>
+</elem-783>
+</elem-782>
+</elem-781>
+</elem-780>
+</elem-779>
+</elem-778>
+</elem-777>
+</elem-776>
+</elem-775>
+</elem-774>
+</elem-773>
+</elem-772>
+</elem-771>
+</elem-770>
+</elem-769>
+</elem-768>
+</elem-767>
+</elem-766>
+</elem-765>
+</elem-764>
+</elem-763>
+</elem-762>
+</elem-761>
+</elem-760>
+</elem-759>
+</elem-758>
+</elem-757>
+</elem-756>
+</elem-755>
+</elem-754>
+</elem-753>
+</elem-752>
+</elem-751>
+</elem-750>
+</elem-749>
+</elem-748>
+</elem-747>
+</elem-746>
+</elem-745>
+</elem-744>
+</elem-743>
+</elem-742>
+</elem-741>
+</elem-740>
+</elem-739>
+</elem-738>
+</elem-737>
+</elem-736>
+</elem-735>
+</elem-734>
+</elem-733>
+</elem-732>
+</elem-731>
+</elem-730>
+</elem-729>
+</elem-728>
+</elem-727>
+</elem-726>
+</elem-725>
+</elem-724>
+</elem-723>
+</elem-722>
+</elem-721>
+</elem-720>
+</elem-719>
+</elem-718>
+</elem-717>
+</elem-716>
+</elem-715>
+</elem-714>
+</elem-713>
+</elem-712>
+</elem-711>
+</elem-710>
+</elem-709>
+</elem-708>
+</elem-707>
+</elem-706>
+</elem-705>
+</elem-704>
+</elem-703>
+</elem-702>
+</elem-701>
+</elem-700>
+</elem-699>
+</elem-698>
+</elem-697>
+</elem-696>
+</elem-695>
+</elem-694>
+</elem-693>
+</elem-692>
+</elem-691>
+</elem-690>
+</elem-689>
+</elem-688>
+</elem-687>
+</elem-686>
+</elem-685>
+</elem-684>
+</elem-683>
+</elem-682>
+</elem-681>
+</elem-680>
+</elem-679>
+</elem-678>
+</elem-677>
+</elem-676>
+</elem-675>
+</elem-674>
+</elem-673>
+</elem-672>
+</elem-671>
+</elem-670>
+</elem-669>
+</elem-668>
+</elem-667>
+</elem-666>
+</elem-665>
+</elem-664>
+</elem-663>
+</elem-662>
+</elem-661>
+</elem-660>
+</elem-659>
+</elem-658>
+</elem-657>
+</elem-656>
+</elem-655>
+</elem-654>
+</elem-653>
+</elem-652>
+</elem-651>
+</elem-650>
+</elem-649>
+</elem-648>
+</elem-647>
+</elem-646>
+</elem-645>
+</elem-644>
+</elem-643>
+</elem-642>
+</elem-641>
+</elem-640>
+</elem-639>
+</elem-638>
+</elem-637>
+</elem-636>
+</elem-635>
+</elem-634>
+</elem-633>
+</elem-632>
+</elem-631>
+</elem-630>
+</elem-629>
+</elem-628>
+</elem-627>
+</elem-626>
+</elem-625>
+</elem-624>
+</elem-623>
+</elem-622>
+</elem-621>
+</elem-620>
+</elem-619>
+</elem-618>
+</elem-617>
+</elem-616>
+</elem-615>
+</elem-614>
+</elem-613>
+</elem-612>
+</elem-611>
+</elem-610>
+</elem-609>
+</elem-608>
+</elem-607>
+</elem-606>
+</elem-605>
+</elem-604>
+</elem-603>
+</elem-602>
+</elem-601>
+</elem-600>
+</elem-599>
+</elem-598>
+</elem-597>
+</elem-596>
+</elem-595>
+</elem-594>
+</elem-593>
+</elem-592>
+</elem-591>
+</elem-590>
+</elem-589>
+</elem-588>
+</elem-587>
+</elem-586>
+</elem-585>
+</elem-584>
+</elem-583>
+</elem-582>
+</elem-581>
+</elem-580>
+</elem-579>
+</elem-578>
+</elem-577>
+</elem-576>
+</elem-575>
+</elem-574>
+</elem-573>
+</elem-572>
+</elem-571>
+</elem-570>
+</elem-569>
+</elem-568>
+</elem-567>
+</elem-566>
+</elem-565>
+</elem-564>
+</elem-563>
+</elem-562>
+</elem-561>
+</elem-560>
+</elem-559>
+</elem-558>
+</elem-557>
+</elem-556>
+</elem-555>
+</elem-554>
+</elem-553>
+</elem-552>
+</elem-551>
+</elem-550>
+</elem-549>
+</elem-548>
+</elem-547>
+</elem-546>
+</elem-545>
+</elem-544>
+</elem-543>
+</elem-542>
+</elem-541>
+</elem-540>
+</elem-539>
+</elem-538>
+</elem-537>
+</elem-536>
+</elem-535>
+</elem-534>
+</elem-533>
+</elem-532>
+</elem-531>
+</elem-530>
+</elem-529>
+</elem-528>
+</elem-527>
+</elem-526>
+</elem-525>
+</elem-524>
+</elem-523>
+</elem-522>
+</elem-521>
+</elem-520>
+</elem-519>
+</elem-518>
+</elem-517>
+</elem-516>
+</elem-515>
+</elem-514>
+</elem-513>
+</elem-512>
+</elem-511>
+</elem-510>
+</elem-509>
+</elem-508>
+</elem-507>
+</elem-506>
+</elem-505>
+</elem-504>
+</elem-503>
+</elem-502>
+</elem-501>
+</elem-500>
+</elem-499>
+</elem-498>
+</elem-497>
+</elem-496>
+</elem-495>
+</elem-494>
+</elem-493>
+</elem-492>
+</elem-491>
+</elem-490>
+</elem-489>
+</elem-488>
+</elem-487>
+</elem-486>
+</elem-485>
+</elem-484>
+</elem-483>
+</elem-482>
+</elem-481>
+</elem-480>
+</elem-479>
+</elem-478>
+</elem-477>
+</elem-476>
+</elem-475>
+</elem-474>
+</elem-473>
+</elem-472>
+</elem-471>
+</elem-470>
+</elem-469>
+</elem-468>
+</elem-467>
+</elem-466>
+</elem-465>
+</elem-464>
+</elem-463>
+</elem-462>
+</elem-461>
+</elem-460>
+</elem-459>
+</elem-458>
+</elem-457>
+</elem-456>
+</elem-455>
+</elem-454>
+</elem-453>
+</elem-452>
+</elem-451>
+</elem-450>
+</elem-449>
+</elem-448>
+</elem-447>
+</elem-446>
+</elem-445>
+</elem-444>
+</elem-443>
+</elem-442>
+</elem-441>
+</elem-440>
+</elem-439>
+</elem-438>
+</elem-437>
+</elem-436>
+</elem-435>
+</elem-434>
+</elem-433>
+</elem-432>
+</elem-431>
+</elem-430>
+</elem-429>
+</elem-428>
+</elem-427>
+</elem-426>
+</elem-425>
+</elem-424>
+</elem-423>
+</elem-422>
+</elem-421>
+</elem-420>
+</elem-419>
+</elem-418>
+</elem-417>
+</elem-416>
+</elem-415>
+</elem-414>
+</elem-413>
+</elem-412>
+</elem-411>
+</elem-410>
+</elem-409>
+</elem-408>
+</elem-407>
+</elem-406>
+</elem-405>
+</elem-404>
+</elem-403>
+</elem-402>
+</elem-401>
+</elem-400>
+</elem-399>
+</elem-398>
+</elem-397>
+</elem-396>
+</elem-395>
+</elem-394>
+</elem-393>
+</elem-392>
+</elem-391>
+</elem-390>
+</elem-389>
+</elem-388>
+</elem-387>
+</elem-386>
+</elem-385>
+</elem-384>
+</elem-383>
+</elem-382>
+</elem-381>
+</elem-380>
+</elem-379>
+</elem-378>
+</elem-377>
+</elem-376>
+</elem-375>
+</elem-374>
+</elem-373>
+</elem-372>
+</elem-371>
+</elem-370>
+</elem-369>
+</elem-368>
+</elem-367>
+</elem-366>
+</elem-365>
+</elem-364>
+</elem-363>
+</elem-362>
+</elem-361>
+</elem-360>
+</elem-359>
+</elem-358>
+</elem-357>
+</elem-356>
+</elem-355>
+</elem-354>
+</elem-353>
+</elem-352>
+</elem-351>
+</elem-350>
+</elem-349>
+</elem-348>
+</elem-347>
+</elem-346>
+</elem-345>
+</elem-344>
+</elem-343>
+</elem-342>
+</elem-341>
+</elem-340>
+</elem-339>
+</elem-338>
+</elem-337>
+</elem-336>
+</elem-335>
+</elem-334>
+</elem-333>
+</elem-332>
+</elem-331>
+</elem-330>
+</elem-329>
+</elem-328>
+</elem-327>
+</elem-326>
+</elem-325>
+</elem-324>
+</elem-323>
+</elem-322>
+</elem-321>
+</elem-320>
+</elem-319>
+</elem-318>
+</elem-317>
+</elem-316>
+</elem-315>
+</elem-314>
+</elem-313>
+</elem-312>
+</elem-311>
+</elem-310>
+</elem-309>
+</elem-308>
+</elem-307>
+</elem-306>
+</elem-305>
+</elem-304>
+</elem-303>
+</elem-302>
+</elem-301>
+</elem-300>
+</elem-299>
+</elem-298>
+</elem-297>
+</elem-296>
+</elem-295>
+</elem-294>
+</elem-293>
+</elem-292>
+</elem-291>
+</elem-290>
+</elem-289>
+</elem-288>
+</elem-287>
+</elem-286>
+</elem-285>
+</elem-284>
+</elem-283>
+</elem-282>
+</elem-281>
+</elem-280>
+</elem-279>
+</elem-278>
+</elem-277>
+</elem-276>
+</elem-275>
+</elem-274>
+</elem-273>
+</elem-272>
+</elem-271>
+</elem-270>
+</elem-269>
+</elem-268>
+</elem-267>
+</elem-266>
+</elem-265>
+</elem-264>
+</elem-263>
+</elem-262>
+</elem-261>
+</elem-260>
+</elem-259>
+</elem-258>
+</elem-257>
+</elem-256>
+</elem-255>
+</elem-254>
+</elem-253>
+</elem-252>
+</elem-251>
+</elem-250>
+</elem-249>
+</elem-248>
+</elem-247>
+</elem-246>
+</elem-245>
+</elem-244>
+</elem-243>
+</elem-242>
+</elem-241>
+</elem-240>
+</elem-239>
+</elem-238>
+</elem-237>
+</elem-236>
+</elem-235>
+</elem-234>
+</elem-233>
+</elem-232>
+</elem-231>
+</elem-230>
+</elem-229>
+</elem-228>
+</elem-227>
+</elem-226>
+</elem-225>
+</elem-224>
+</elem-223>
+</elem-222>
+</elem-221>
+</elem-220>
+</elem-219>
+</elem-218>
+</elem-217>
+</elem-216>
+</elem-215>
+</elem-214>
+</elem-213>
+</elem-212>
+</elem-211>
+</elem-210>
+</elem-209>
+</elem-208>
+</elem-207>
+</elem-206>
+</elem-205>
+</elem-204>
+</elem-203>
+</elem-202>
+</elem-201>
+</elem-200>
+</elem-199>
+</elem-198>
+</elem-197>
+</elem-196>
+</elem-195>
+</elem-194>
+</elem-193>
+</elem-192>
+</elem-191>
+</elem-190>
+</elem-189>
+</elem-188>
+</elem-187>
+</elem-186>
+</elem-185>
+</elem-184>
+</elem-183>
+</elem-182>
+</elem-181>
+</elem-180>
+</elem-179>
+</elem-178>
+</elem-177>
+</elem-176>
+</elem-175>
+</elem-174>
+</elem-173>
+</elem-172>
+</elem-171>
+</elem-170>
+</elem-169>
+</elem-168>
+</elem-167>
+</elem-166>
+</elem-165>
+</elem-164>
+</elem-163>
+</elem-162>
+</elem-161>
+</elem-160>
+</elem-159>
+</elem-158>
+</elem-157>
+</elem-156>
+</elem-155>
+</elem-154>
+</elem-153>
+</elem-152>
+</elem-151>
+</elem-150>
+</elem-149>
+</elem-148>
+</elem-147>
+</elem-146>
+</elem-145>
+</elem-144>
+</elem-143>
+</elem-142>
+</elem-141>
+</elem-140>
+</elem-139>
+</elem-138>
+</elem-137>
+</elem-136>
+</elem-135>
+</elem-134>
+</elem-133>
+</elem-132>
+</elem-131>
+</elem-130>
+</elem-129>
+</elem-128>
+</elem-127>
+</elem-126>
+</elem-125>
+</elem-124>
+</elem-123>
+</elem-122>
+</elem-121>
+</elem-120>
+</elem-119>
+</elem-118>
+</elem-117>
+</elem-116>
+</elem-115>
+</elem-114>
+</elem-113>
+</elem-112>
+</elem-111>
+</elem-110>
+</elem-109>
+</elem-108>
+</elem-107>
+</elem-106>
+</elem-105>
+</elem-104>
+</elem-103>
+</elem-102>
+</elem-101>
+</elem-100>
+</elem-99>
+</elem-98>
+</elem-97>
+</elem-96>
+</elem-95>
+</elem-94>
+</elem-93>
+</elem-92>
+</elem-91>
+</elem-90>
+</elem-89>
+</elem-88>
+</elem-87>
+</elem-86>
+</elem-85>
+</elem-84>
+</elem-83>
+</elem-82>
+</elem-81>
+</elem-80>
+</elem-79>
+</elem-78>
+</elem-77>
+</elem-76>
+</elem-75>
+</elem-74>
+</elem-73>
+</elem-72>
+</elem-71>
+</elem-70>
+</elem-69>
+</elem-68>
+</elem-67>
+</elem-66>
+</elem-65>
+</elem-64>
+</elem-63>
+</elem-62>
+</elem-61>
+</elem-60>
+</elem-59>
+</elem-58>
+</elem-57>
+</elem-56>
+</elem-55>
+</elem-54>
+</elem-53>
+</elem-52>
+</elem-51>
+</elem-50>
+</elem-49>
+</elem-48>
+</elem-47>
+</elem-46>
+</elem-45>
+</elem-44>
+</elem-43>
+</elem-42>
+</elem-41>
+</elem-40>
+</elem-39>
+</elem-38>
+</elem-37>
+</elem-36>
+</elem-35>
+</elem-34>
+</elem-33>
+</elem-32>
+</elem-31>
+</elem-30>
+</elem-29>
+</elem-28>
+</elem-27>
+</elem-26>
+</elem-25>
+</elem-24>
+</elem-23>
+</elem-22>
+</elem-21>
+</elem-20>
+</elem-19>
+</elem-18>
+</elem-17>
+</elem-16>
+</elem-15>
+</elem-14>
+</elem-13>
+</elem-12>
+</elem-11>
+</elem-10>
+</elem-9>
+</elem-8>
+</elem-7>
+</elem-6>
+</elem-5>
+</elem-4>
+</elem-3>
+</elem-2>
+</elem-1>
+</outer> \ No newline at end of file
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestRazorProject.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestRazorProject.cs
new file mode 100644
index 0000000000..24b3c8eaf4
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/TestRazorProject.cs
@@ -0,0 +1,41 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class TestRazorProject : RazorProject
+ {
+ private readonly Dictionary<string, RazorProjectItem> _lookup;
+
+ public TestRazorProject()
+ : this(new RazorProjectItem[0])
+ {
+ }
+
+ public TestRazorProject(IList<RazorProjectItem> items)
+ {
+ _lookup = items.ToDictionary(item => item.FilePath);
+ }
+
+ public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override RazorProjectItem GetItem(string path)
+ {
+ if (!_lookup.TryGetValue(path, out var value))
+ {
+ value = new NotFoundProjectItem("", path);
+ }
+
+ return value;
+ }
+
+ public new string NormalizeAndEnsureValidPath(string path) => base.NormalizeAndEnsureValidPath(path);
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/VirtualRazorProjectFileSystemTest.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/VirtualRazorProjectFileSystemTest.cs
new file mode 100644
index 0000000000..f4501b1321
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/VirtualRazorProjectFileSystemTest.cs
@@ -0,0 +1,400 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Xunit;
+using DirectoryNode = Microsoft.AspNetCore.Razor.Language.VirtualRazorProjectFileSystem.DirectoryNode;
+using FileNode = Microsoft.AspNetCore.Razor.Language.VirtualRazorProjectFileSystem.FileNode;
+
+namespace Microsoft.AspNetCore.Razor.Language
+{
+ public class VirtualRazorProjectFileSystemTest
+ {
+ [Fact]
+ public void GetItem_ReturnsNotFound_IfFileDoesNotExistInRoot()
+ {
+ // Arrange
+ var path = "/root-file.cshtml";
+ var projectSystem = new VirtualRazorProjectFileSystem();
+
+ // Act
+ projectSystem.Add(new TestRazorProjectItem("/different-file.cshtml"));
+ var result = projectSystem.GetItem(path);
+
+ // Assert
+ Assert.False(result.Exists);
+ }
+
+ [Fact]
+ public void GetItem_ReturnsItemAddedToRoot()
+ {
+ // Arrange
+ var path = "/root-file.cshtml";
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var projectItem = new TestRazorProjectItem(path);
+
+ // Act
+ projectSystem.Add(projectItem);
+ var actual = projectSystem.GetItem(path);
+
+ // Assert
+ Assert.Same(projectItem, actual);
+ }
+
+ [Theory]
+ [InlineData("/subDirectory/file.cshtml")]
+ [InlineData("/subDirectory/dir2/file.cshtml")]
+ [InlineData("/subDirectory/dir2/dir3/file.cshtml")]
+ public void GetItem_ReturnsItemAddedToNestedDirectory(string path)
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var projectItem = new TestRazorProjectItem(path);
+
+ // Act
+ projectSystem.Add(projectItem);
+ var actual = projectSystem.GetItem(path);
+
+ // Assert
+ Assert.Same(projectItem, actual);
+ }
+
+ [Fact]
+ public void GetItem_ReturnsNotFound_WhenNestedDirectoryDoesNotExist()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+
+ // Act
+ var actual = projectSystem.GetItem("/subDirectory/dir3/file.cshtml");
+
+ // Assert
+ Assert.False(actual.Exists);
+ }
+
+ [Fact]
+ public void GetItem_ReturnsNotFound_WhenNestedDirectoryDoesNotExist_AndPeerDirectoryExists()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var projectItem = new TestRazorProjectItem("/subDirectory/dir2/file.cshtml");
+
+ // Act
+ projectSystem.Add(projectItem);
+ var actual = projectSystem.GetItem("/subDirectory/dir3/file.cshtml");
+
+ // Assert
+ Assert.False(actual.Exists);
+ }
+
+ [Fact]
+ public void GetItem_ReturnsNotFound_WhenFileDoesNotExistInNestedDirectory()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var projectItem = new TestRazorProjectItem("/subDirectory/dir2/file.cshtml");
+
+ // Act
+ projectSystem.Add(projectItem);
+ var actual = projectSystem.GetItem("/subDirectory/dir2/file2.cshtml");
+
+ // Assert
+ Assert.False(actual.Exists);
+ }
+
+ [Fact]
+ public void EnumerateItems_AtRoot_ReturnsAllFiles()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var file1 = new TestRazorProjectItem("/subDirectory/dir2/file1.cshtml");
+ var file2 = new TestRazorProjectItem("/file2.cshtml");
+ var file3 = new TestRazorProjectItem("/dir3/file3.cshtml");
+ var file4 = new TestRazorProjectItem("/subDirectory/file4.cshtml");
+ projectSystem.Add(file1);
+ projectSystem.Add(file2);
+ projectSystem.Add(file3);
+ projectSystem.Add(file4);
+
+ // Act
+ var result = projectSystem.EnumerateItems("/");
+
+ // Assert
+ Assert.Equal(new[] { file2, file4, file1, file3 }, result);
+ }
+
+ [Fact]
+ public void EnumerateItems_AtSubDirectory_ReturnsAllFilesUnderDirectoryHierarchy()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var file1 = new TestRazorProjectItem("/subDirectory/dir2/file1.cshtml");
+ var file2 = new TestRazorProjectItem("/file2.cshtml");
+ var file3 = new TestRazorProjectItem("/dir3/file3.cshtml");
+ var file4 = new TestRazorProjectItem("/subDirectory/file4.cshtml");
+ projectSystem.Add(file1);
+ projectSystem.Add(file2);
+ projectSystem.Add(file3);
+ projectSystem.Add(file4);
+
+ // Act
+ var result = projectSystem.EnumerateItems("/subDirectory");
+
+ // Assert
+ Assert.Equal(new[] { file4, file1 }, result);
+ }
+
+ [Fact]
+ public void EnumerateItems_WithNoFilesInRoot_ReturnsEmptySequence()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+
+ // Act
+ var result = projectSystem.EnumerateItems("/");
+
+ // Assert
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void EnumerateItems_ForNonExistentDirectory_ReturnsEmptySequence()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ projectSystem.Add(new TestRazorProjectItem("/subDirectory/dir2/file1.cshtml"));
+ projectSystem.Add(new TestRazorProjectItem("/file2.cshtml"));
+
+ // Act
+ var result = projectSystem.EnumerateItems("/dir3");
+
+ // Assert
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void GetHierarchicalItems_Works()
+ {
+ // Arrange
+ var projectSystem = new VirtualRazorProjectFileSystem();
+ var viewImport1 = new TestRazorProjectItem("/_ViewImports.cshtml");
+ var viewImport2 = new TestRazorProjectItem("/Views/Home/_ViewImports.cshtml");
+ projectSystem.Add(viewImport1);
+ projectSystem.Add(viewImport2);
+
+ // Act
+ var items = projectSystem.FindHierarchicalItems("/", "/Views/Home/Index.cshtml", "_ViewImports.cshtml");
+
+ // Assert
+ Assert.Collection(
+ items,
+ item => Assert.Same(viewImport2, item),
+ item => Assert.False(item.Exists),
+ item => Assert.Same(viewImport1, item));
+ }
+
+ [Fact]
+ public void DirectoryNode_GetDirectory_ReturnsRoot()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+
+ // Act
+ var result = root.GetDirectory("/");
+
+ // Assert
+ Assert.Same(root, result);
+ }
+
+ [Fact]
+ public void DirectoryNode_GetDirectory_ReturnsNull_IfDirectoryDoesNotExist()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+
+ // Act
+ var result = root.GetDirectory("/does-not/exist");
+
+ // Assert
+ Assert.Null(result);
+ }
+
+ [Fact]
+ public void DirectoryNode_AddFile_CanAddToRoot()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem = new TestRazorProjectItem("/File.txt");
+
+ // Act
+ root.AddFile(new FileNode("/File.txt", projectItem));
+
+ // Assert
+ Assert.Empty(root.Directories);
+ Assert.Collection(
+ root.Files,
+ file => Assert.Same(projectItem, file.ProjectItem));
+ }
+
+ [Fact]
+ public void DirectoryNode_AddFile_CanAddToNestedDirectory()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem = new TestRazorProjectItem("/Pages/Shared/_Layout.cshtml");
+
+ // Act
+ root.AddFile(new FileNode("/Pages/Shared/_Layout.cshtml", projectItem));
+
+ // Assert
+ Assert.Collection(
+ root.Directories,
+ directory =>
+ {
+ Assert.Equal("/Pages/", directory.Path);
+ Assert.Empty(directory.Files);
+
+ Assert.Collection(
+ directory.Directories,
+ subDirectory =>
+ {
+ Assert.Equal("/Pages/Shared/", subDirectory.Path);
+ Assert.Collection(
+ subDirectory.Files,
+ file => Assert.Same(projectItem, file.ProjectItem));
+ });
+ });
+ }
+
+ [Fact]
+ public void DirectoryNode_AddMultipleFiles_ToSameDirectory()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem1 = new TestRazorProjectItem("/Pages/Shared/_Layout.cshtml");
+ var projectItem2 = new TestRazorProjectItem("/Pages/Shared/_Partial.cshtml");
+
+ // Act
+ root.AddFile(new FileNode(projectItem1.FilePath, projectItem1));
+ root.AddFile(new FileNode(projectItem2.FilePath, projectItem2));
+
+ // Assert
+ Assert.Collection(
+ root.Directories,
+ directory =>
+ {
+ Assert.Equal("/Pages/", directory.Path);
+ Assert.Empty(directory.Files);
+
+ Assert.Collection(
+ directory.Directories,
+ subDirectory =>
+ {
+ Assert.Equal("/Pages/Shared/", subDirectory.Path);
+ Assert.Collection(
+ subDirectory.Files,
+ file => Assert.Same(projectItem1, file.ProjectItem),
+ file => Assert.Same(projectItem2, file.ProjectItem));
+ });
+ });
+ }
+
+ [Fact]
+ public void DirectoryNode_AddsFiles_ToSiblingDirectories()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem1 = new TestRazorProjectItem("/Pages/Products/Index.cshtml");
+ var projectItem2 = new TestRazorProjectItem("/Pages/Accounts/About.cshtml");
+
+ // Act
+ root.AddFile(new FileNode(projectItem1.FilePath, projectItem1));
+ root.AddFile(new FileNode(projectItem2.FilePath, projectItem2));
+
+ // Assert
+ Assert.Collection(
+ root.Directories,
+ directory =>
+ {
+ Assert.Equal("/Pages/", directory.Path);
+ Assert.Empty(directory.Files);
+
+ Assert.Collection(
+ directory.Directories,
+ subDirectory =>
+ {
+ Assert.Equal("/Pages/Products/", subDirectory.Path);
+ Assert.Collection(
+ subDirectory.Files,
+ file => Assert.Same(projectItem1, file.ProjectItem));
+ },
+ subDirectory =>
+ {
+ Assert.Equal("/Pages/Accounts/", subDirectory.Path);
+ Assert.Collection(
+ subDirectory.Files,
+ file => Assert.Same(projectItem2, file.ProjectItem));
+ });
+ });
+ }
+
+ [Fact]
+ public void DirectoryNode_GetItem_ReturnsItemAtRoot()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem = new TestRazorProjectItem("/_ViewStart.cshtml");
+ root.AddFile(new FileNode(projectItem.FilePath, projectItem));
+
+ // Act
+ var result = root.GetItem(projectItem.FilePath);
+
+ // Assert
+ Assert.Same(result, projectItem);
+ }
+
+ [Fact]
+ public void DirectoryNode_GetItem_WhenFilePathSharesSameNameAsSiblingDirectory()
+ {
+ // Arrange
+ var root = new DirectoryNode("/");
+ var projectItem1 = new TestRazorProjectItem("/Home.cshtml");
+ var projectItem2 = new TestRazorProjectItem("/Home/About.cshtml");
+ root.AddFile(new FileNode(projectItem1.FilePath, projectItem1));
+ root.AddFile(new FileNode(projectItem2.FilePath, projectItem2));
+
+ // Act
+ var result = root.GetItem(projectItem1.FilePath);
+
+ // Assert
+ Assert.Same(result, projectItem1);
+ }
+
+ [Fact]
+ public void DirectoryNode_GetItem_WhenFileNameIsSameAsDirectoryName()
+ {
+ // Arrange
+ var projectItem1 = new TestRazorProjectItem("/Home/Home.cshtml");
+ var projectItem2 = new TestRazorProjectItem("/Home/About.cshtml");
+ var root = new DirectoryNode("/")
+ {
+ Directories =
+ {
+ new DirectoryNode("/Home/")
+ {
+ Files =
+ {
+ new FileNode(projectItem1.FilePath, projectItem1),
+ new FileNode(projectItem2.FilePath, projectItem2),
+ }
+ }
+ },
+ };
+
+ // Act
+ var result = root.GetItem(projectItem1.FilePath);
+
+ // Assert
+ Assert.Same(result, projectItem1);
+ }
+ }
+}
diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/xunit.runner.json b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/xunit.runner.json
new file mode 100644
index 0000000000..fcf172c8fc
--- /dev/null
+++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Language.Test/xunit.runner.json
@@ -0,0 +1,4 @@
+{
+ "methodDisplay": "method",
+ "shadowCopy": false
+} \ No newline at end of file